diff --git a/.env.dev b/.env.dev index 232f1c6b..2008a002 100644 --- a/.env.dev +++ b/.env.dev @@ -8,8 +8,6 @@ VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn' # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务 VITE_UPLOAD_TYPE=server -# 上传路径 -VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload' # 接口地址 VITE_API_URL=/admin-api diff --git a/.env.local b/.env.local index 005d2f0d..ad084700 100644 --- a/.env.local +++ b/.env.local @@ -8,8 +8,6 @@ VITE_BASE_URL='http://localhost:48080' # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务 VITE_UPLOAD_TYPE=server -# 上传路径 -VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload' # 接口地址 VITE_API_URL=/admin-api diff --git a/.env.prod b/.env.prod index 842ba616..8b78c415 100644 --- a/.env.prod +++ b/.env.prod @@ -8,8 +8,6 @@ VITE_BASE_URL='http://localhost:48080' # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务 VITE_UPLOAD_TYPE=server -# 上传路径 -VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload' # 接口地址 VITE_API_URL=/admin-api diff --git a/.env.stage b/.env.stage index f7c521bd..3d005c7b 100644 --- a/.env.stage +++ b/.env.stage @@ -8,8 +8,6 @@ VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn' # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务 VITE_UPLOAD_TYPE=server -# 上传路径 -VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload' # 接口地址 VITE_API_URL=/admin-api diff --git a/.env.test b/.env.test index 7bf1b417..80f4c660 100644 --- a/.env.test +++ b/.env.test @@ -8,8 +8,6 @@ VITE_BASE_URL='http://localhost:48080' # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务 VITE_UPLOAD_TYPE=server -# 上传路径 -VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload' # 接口地址 VITE_API_URL=/admin-api diff --git a/.vscode/settings.json b/.vscode/settings.json index 7d8aed49..f145f386 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -87,7 +87,7 @@ "source.fixAll.stylelint": "explicit" }, "[vue]": { - "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" + "editor.defaultFormatter": "esbenp.prettier-vscode" }, "i18n-ally.localesPaths": ["src/locales"], "i18n-ally.keystyle": "nested", diff --git a/package.json b/package.json index 8da17220..4ceb4b91 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "vite-plugin-progress": "^0.0.7", "vite-plugin-purge-icons": "^0.10.0", "vite-plugin-svg-icons": "^2.0.1", - "vite-plugin-top-level-await": "^1.3.1", + "vite-plugin-top-level-await": "^1.4.4", "vue-eslint-parser": "^9.3.2", "vue-tsc": "^1.8.27" }, diff --git a/src/api/iot/device/index.ts b/src/api/iot/device/index.ts new file mode 100644 index 00000000..903874b7 --- /dev/null +++ b/src/api/iot/device/index.ts @@ -0,0 +1,74 @@ +import request from '@/config/axios' + +// IoT 设备 VO +export interface DeviceVO { + id: number // 设备 ID,主键,自增 + deviceKey: string // 设备唯一标识符 + deviceName: string // 设备名称 + productId: number // 产品编号 + productKey: string // 产品标识 + deviceType: number // 设备类型 + nickname: string // 设备备注名称 + gatewayId: number // 网关设备 ID + status: number // 设备状态 + statusLastUpdateTime: Date // 设备状态最后更新时间 + lastOnlineTime: Date // 最后上线时间 + lastOfflineTime: Date // 最后离线时间 + activeTime: Date // 设备激活时间 + createTime: Date // 创建时间 + ip: string // 设备的 IP 地址 + firmwareVersion: string // 设备的固件版本 + deviceSecret: string // 设备密钥,用于设备认证,需安全存储 + mqttClientId: string // MQTT 客户端 ID + mqttUsername: string // MQTT 用户名 + mqttPassword: string // MQTT 密码 + authType: string // 认证类型 + latitude: number // 设备位置的纬度 + longitude: number // 设备位置的经度 + areaId: number // 地区编码 + address: string // 设备详细地址 + serialNumber: string // 设备序列号 +} + +export interface DeviceUpdateStatusVO { + id: number // 设备 ID,主键,自增 + status: number // 设备状态 +} + +// 设备 API +export const DeviceApi = { + // 查询设备分页 + getDevicePage: async (params: any) => { + return await request.get({ url: `/iot/device/page`, params }) + }, + + // 查询设备详情 + getDevice: async (id: number) => { + return await request.get({ url: `/iot/device/get?id=` + id }) + }, + + // 新增设备 + createDevice: async (data: DeviceVO) => { + return await request.post({ url: `/iot/device/create`, data }) + }, + + // 修改设备 + updateDevice: async (data: DeviceVO) => { + return await request.put({ url: `/iot/device/update`, data }) + }, + + // 修改设备状态 + updateDeviceStatus: async (data: DeviceUpdateStatusVO) => { + return await request.put({ url: `/iot/device/update-status`, data }) + }, + + // 删除设备 + deleteDevice: async (id: number) => { + return await request.delete({ url: `/iot/device/delete?id=` + id }) + }, + + // 获取设备数量 + getDeviceCount: async (productId: number) => { + return await request.get({ url: `/iot/device/count?productId=` + productId }) + } +} diff --git a/src/api/iot/product/index.ts b/src/api/iot/product/index.ts new file mode 100644 index 00000000..1ffa490d --- /dev/null +++ b/src/api/iot/product/index.ts @@ -0,0 +1,62 @@ +import request from '@/config/axios' + +// IoT 产品 VO +export interface ProductVO { + id: number // 产品编号 + name: string // 产品名称 + productKey: string // 产品标识 + protocolId: number // 协议编号 + categoryId: number // 产品所属品类标识符 + description: string // 产品描述 + validateType: number // 数据校验级别 + status: number // 产品状态 + deviceType: number // 设备类型 + netType: number // 联网方式 + protocolType: number // 接入网关协议 + dataFormat: number // 数据格式 + deviceCount: number // 设备数量 + createTime: Date // 创建时间 +} + +// IoT 产品 API +export const ProductApi = { + // 查询产品分页 + getProductPage: async (params: any) => { + return await request.get({ url: `/iot/product/page`, params }) + }, + + // 查询产品详情 + getProduct: async (id: number) => { + return await request.get({ url: `/iot/product/get?id=` + id }) + }, + + // 新增产品 + createProduct: async (data: ProductVO) => { + return await request.post({ url: `/iot/product/create`, data }) + }, + + // 修改产品 + updateProduct: async (data: ProductVO) => { + return await request.put({ url: `/iot/product/update`, data }) + }, + + // 删除产品 + deleteProduct: async (id: number) => { + return await request.delete({ url: `/iot/product/delete?id=` + id }) + }, + + // 导出产品 Excel + exportProduct: async (params) => { + return await request.download({ url: `/iot/product/export-excel`, params }) + }, + + // 更新产品状态 + updateProductStatus: async (id: number, status: number) => { + return await request.put({ url: `/iot/product/update-status?id=` + id + `&status=` + status }) + }, + + // 查询产品(精简)列表 + getSimpleProductList() { + return request.get({ url: '/iot/product/list-all-simple' }) + } +} diff --git a/src/api/iot/thinkmodelfunction/index.ts b/src/api/iot/thinkmodelfunction/index.ts new file mode 100644 index 00000000..bd2e2d0f --- /dev/null +++ b/src/api/iot/thinkmodelfunction/index.ts @@ -0,0 +1,55 @@ +import request from '@/config/axios' + +// IoT 产品物模型 VO +export interface ThinkModelFunctionVO { + id: number // 物模型功能编号 + identifier: string // 功能标识 + name: string // 功能名称 + description: string // 功能描述 + productId: number // 产品编号 + productKey: string // 产品标识 + type: number // 功能类型 + property: string // 属性 + event: string // 事件 + service: string // 服务 +} + +// IoT 产品物模型 API +export const ThinkModelFunctionApi = { + // 查询产品物模型分页 + getThinkModelFunctionPage: async (params: any) => { + return await request.get({ url: `/iot/think-model-function/page`, params }) + }, + // 获得产品物模型 + getThinkModelFunctionListByProductId: async (params: any) => { + return await request.get({ + url: `/iot/think-model-function/list-by-product-id`, + params + }) + }, + + // 查询产品物模型详情 + getThinkModelFunction: async (id: number) => { + return await request.get({ url: `/iot/think-model-function/get?id=` + id }) + }, + + // 新增产品物模型 + createThinkModelFunction: async (data: ThinkModelFunctionVO) => { + return await request.post({ url: `/iot/think-model-function/create`, data }) + }, + + // 修改产品物模型 + updateThinkModelFunction: async (data: ThinkModelFunctionVO) => { + return await request.put({ url: `/iot/think-model-function/update`, data }) + }, + + // 删除产品物模型 + deleteThinkModelFunction: async (id: number) => { + return await request.delete({ url: `/iot/think-model-function/delete?id=` + id }) + }, + + // 导出产品物模型 Excel + exportThinkModelFunction: async (params) => { + return await request.download({ url: `/iot/think-model-function/export-excel`, params }) + } +} diff --git a/src/api/login/index.ts b/src/api/login/index.ts index ef86563b..dec14fb3 100644 --- a/src/api/login/index.ts +++ b/src/api/login/index.ts @@ -1,6 +1,6 @@ import request from '@/config/axios' import { getRefreshToken } from '@/utils/auth' -import type { UserLoginVO } from './types' +import type { RegisterVO, UserLoginVO } from './types' export interface SmsCodeVO { mobile: string @@ -17,6 +17,11 @@ export const login = (data: UserLoginVO) => { return request.post({ url: '/system/auth/login', data }) } +// 注册 +export const register = (data: RegisterVO) => { + return request.post({ url: '/system/auth/register', data }) +} + // 刷新访问令牌 export const refreshToken = () => { return request.post({ url: '/system/auth/refresh-token?refreshToken=' + getRefreshToken() }) diff --git a/src/api/login/types.ts b/src/api/login/types.ts index fff81225..b5790e62 100644 --- a/src/api/login/types.ts +++ b/src/api/login/types.ts @@ -29,3 +29,10 @@ export type UserVO = { loginIp: string loginDate: string } + +export type RegisterVO = { + tenantName: string + username: string + password: string + captchaVerification: string +} diff --git a/src/api/mall/promotion/point/index.ts b/src/api/mall/promotion/point/index.ts new file mode 100644 index 00000000..38254c2d --- /dev/null +++ b/src/api/mall/promotion/point/index.ts @@ -0,0 +1,91 @@ +import request from '@/config/axios' +import { Sku, Spu } from '@/api/mall/product/spu' // 积分商城活动 VO + +// 积分商城活动 VO +export interface PointActivityVO { + id: number // 积分商城活动编号 + spuId: number // 积分商城活动商品 + status: number // 活动状态 + stock: number // 积分商城活动库存 + totalStock: number // 积分商城活动总库存 + remark?: string // 备注 + sort: number // 排序 + createTime: string // 创建时间 + products: PointProductVO[] // 积分商城商品 + + // ========== 商品字段 ========== + spuName: string // 商品名称 + picUrl: string // 商品主图 + marketPrice: number // 商品市场价,单位:分 + + //======================= 显示所需兑换积分最少的 sku 信息 ======================= + point: number // 兑换积分 + price: number // 兑换金额,单位:分 +} + +// 秒杀活动所需属性 +export interface PointProductVO { + id?: number // 积分商城商品编号 + activityId?: number // 积分商城活动 id + spuId?: number // 商品 SPU 编号 + skuId: number // 商品 SKU 编号 + count: number // 可兑换数量 + point: number // 兑换积分 + price: number // 兑换金额,单位:分 + stock: number // 积分商城商品库存 + activityStatus?: number // 积分商城商品状态 +} + +// 扩展 Sku 配置 +export type SkuExtension = Sku & { + productConfig: PointProductVO +} + +export interface SpuExtension extends Spu { + skus: SkuExtension[] // 重写类型 +} + +export interface SpuExtension0 extends Spu { + pointStock: number // 积分商城活动库存 + pointTotalStock: number // 积分商城活动总库存 + point: number // 兑换积分 + pointPrice: number // 兑换金额,单位:分 +} + +// 积分商城活动 API +export const PointActivityApi = { + // 查询积分商城活动分页 + getPointActivityPage: async (params: any) => { + return await request.get({ url: `/promotion/point-activity/page`, params }) + }, + + // 查询积分商城活动详情 + getPointActivity: async (id: number) => { + return await request.get({ url: `/promotion/point-activity/get?id=` + id }) + }, + + // 查询积分商城活动列表,基于活动编号数组 + getPointActivityListByIds: async (ids: number[]) => { + return request.get({ url: `/promotion/point-activity/list-by-ids?ids=${ids}` }) + }, + + // 新增积分商城活动 + createPointActivity: async (data: PointActivityVO) => { + return await request.post({ url: `/promotion/point-activity/create`, data }) + }, + + // 修改积分商城活动 + updatePointActivity: async (data: PointActivityVO) => { + return await request.put({ url: `/promotion/point-activity/update`, data }) + }, + + // 删除积分商城活动 + deletePointActivity: async (id: number) => { + return await request.delete({ url: `/promotion/point-activity/delete?id=` + id }) + }, + + // 关闭秒杀活动 + closePointActivity: async (id: number) => { + return await request.put({ url: '/promotion/point-activity/close?id=' + id }) + } +} diff --git a/src/api/mall/promotion/reward/rewardActivity.ts b/src/api/mall/promotion/reward/rewardActivity.ts index 09f32ac5..e9f95ed8 100644 --- a/src/api/mall/promotion/reward/rewardActivity.ts +++ b/src/api/mall/promotion/reward/rewardActivity.ts @@ -47,7 +47,12 @@ export const getReward = async (id: number) => { return await request.get({ url: '/promotion/reward-activity/get?id=' + id }) } -// 删除限时折扣活动 +// 删除满减送活动 export const deleteRewardActivity = async (id: number) => { return await request.delete({ url: '/promotion/reward-activity/delete?id=' + id }) } + +// 关闭满减送活动 +export const closeRewardActivity = async (id: number) => { + return await request.put({ url: '/promotion/reward-activity/close?id=' + id }) +} diff --git a/src/api/mall/promotion/seckill/seckillActivity.ts b/src/api/mall/promotion/seckill/seckillActivity.ts index 4bb0e8b1..dc5a350a 100644 --- a/src/api/mall/promotion/seckill/seckillActivity.ts +++ b/src/api/mall/promotion/seckill/seckillActivity.ts @@ -18,6 +18,7 @@ export interface SeckillActivityVO { singleLimitCount?: number stock?: number totalStock?: number + seckillPrice?: number products?: SeckillProductVO[] } @@ -43,6 +44,11 @@ export const getSeckillActivityPage = async (params) => { return await request.get({ url: '/promotion/seckill-activity/page', params }) } +// 查询秒杀活动列表,基于活动编号数组 +export const getSeckillActivityListByIds = (ids: number[]) => { + return request.get({ url: `/promotion/seckill-activity/list-by-ids?ids=${ids}` }) +} + // 查询秒杀活动详情 export const getSeckillActivity = async (id: number) => { return await request.get({ url: '/promotion/seckill-activity/get?id=' + id }) diff --git a/src/api/pay/order/index.ts b/src/api/pay/order/index.ts index 71960a8a..6460c4d1 100644 --- a/src/api/pay/order/index.ts +++ b/src/api/pay/order/index.ts @@ -84,8 +84,14 @@ export const getOrderPage = async (params: OrderPageReqVO) => { } // 查询详情支付订单 -export const getOrder = async (id: number) => { - return await request.get({ url: '/pay/order/get?id=' + id }) +export const getOrder = async (id: number, sync?: boolean) => { + return await request.get({ + url: '/pay/order/get', + params: { + id, + sync + } + }) } // 获得支付订单的明细 diff --git a/src/components/AppLinkInput/data.ts b/src/components/AppLinkInput/data.ts index 1916e083..c9e3678a 100644 --- a/src/components/AppLinkInput/data.ts +++ b/src/components/AppLinkInput/data.ts @@ -5,6 +5,7 @@ export interface AppLinkGroup { // 链接列表 links: AppLink[] } + // APP 链接 export interface AppLink { // 链接名称 @@ -21,6 +22,8 @@ export const enum APP_LINK_TYPE_ENUM { ACTIVITY_COMBINATION, // 秒杀活动 ACTIVITY_SECKILL, + // 积分商城活动 + ACTIVITY_POINT, // 文章详情 ARTICLE_DETAIL, // 优惠券详情 @@ -130,6 +133,11 @@ export const APP_LINK_GROUP_LIST = [ path: '/pages/activity/seckill/list', type: APP_LINK_TYPE_ENUM.ACTIVITY_SECKILL }, + { + name: '积分商城活动', + path: '/pages/activity/point/list', + type: APP_LINK_TYPE_ENUM.ACTIVITY_POINT + }, { name: '签到中心', path: '/pages/app/sign' diff --git a/src/components/ContentWrap/src/ContentWrap.vue b/src/components/ContentWrap/src/ContentWrap.vue index c75e4b71..e6035963 100644 --- a/src/components/ContentWrap/src/ContentWrap.vue +++ b/src/components/ContentWrap/src/ContentWrap.vue @@ -11,7 +11,7 @@ const prefixCls = getPrefixCls('content-wrap') defineProps({ title: propTypes.string.def(''), message: propTypes.string.def(''), - bodyStyle: propTypes.object.def({ padding: '20px' }) + bodyStyle: propTypes.object.def({ padding: '10px' }) }) diff --git a/src/components/DiyEditor/components/mobile/FloatingActionButton/index.vue b/src/components/DiyEditor/components/mobile/FloatingActionButton/index.vue index 19e42cb6..c2b99263 100644 --- a/src/components/DiyEditor/components/mobile/FloatingActionButton/index.vue +++ b/src/components/DiyEditor/components/mobile/FloatingActionButton/index.vue @@ -44,7 +44,7 @@ defineOptions({ name: 'FloatingActionButton' }) defineProps<{ property: FloatingActionButtonProperty }>() // 是否展开 -const expanded = ref(true) +const expanded = ref(false) // 处理展开/折叠 const handleToggleFab = () => { expanded.value = !expanded.value diff --git a/src/components/DiyEditor/components/mobile/ProductCard/index.vue b/src/components/DiyEditor/components/mobile/ProductCard/index.vue index 78ad84f3..25f8cb87 100644 --- a/src/components/DiyEditor/components/mobile/ProductCard/index.vue +++ b/src/components/DiyEditor/components/mobile/ProductCard/index.vue @@ -67,7 +67,7 @@ class="text-16px" :style="{ color: property.fields.price.color }" > - ¥{{ fenToYuan(spu.price) }} + ¥{{ fenToYuan(spu.price as any) }} import { ProductListProperty } from './config' import * as ProductSpuApi from '@/api/mall/product/spu' -import { fenToYuan } from './index' +import { fenToYuan } from '@/utils' /** 商品栏 */ defineOptions({ name: 'ProductList' }) diff --git a/src/components/DiyEditor/components/mobile/PromotionPoint/config.ts b/src/components/DiyEditor/components/mobile/PromotionPoint/config.ts new file mode 100644 index 00000000..75aa0ffb --- /dev/null +++ b/src/components/DiyEditor/components/mobile/PromotionPoint/config.ts @@ -0,0 +1,96 @@ +import {ComponentStyle, DiyComponent} from '@/components/DiyEditor/util' + +/** 积分商城属性 */ +export interface PromotionPointProperty { + // 布局类型:单列 | 三列 + layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol' + // 商品字段 + fields: { + // 商品名称 + name: PromotionPointFieldProperty + // 商品简介 + introduction: PromotionPointFieldProperty + // 商品价格 + price: PromotionPointFieldProperty + // 市场价 + marketPrice: PromotionPointFieldProperty + // 商品销量 + salesCount: PromotionPointFieldProperty + // 商品库存 + stock: PromotionPointFieldProperty + } + // 角标 + badge: { + // 是否显示 + show: boolean + // 角标图片 + imgUrl: string + } + // 按钮 + btnBuy: { + // 类型:文字 | 图片 + type: 'text' | 'img' + // 文字 + text: string + // 文字按钮:背景渐变起始颜色 + bgBeginColor: string + // 文字按钮:背景渐变结束颜色 + bgEndColor: string + // 图片按钮:图片地址 + imgUrl: string + } + // 上圆角 + borderRadiusTop: number + // 下圆角 + borderRadiusBottom: number + // 间距 + space: number + // 秒杀活动编号 + activityIds: number[] + // 组件样式 + style: ComponentStyle +} + +// 商品字段 +export interface PromotionPointFieldProperty { + // 是否显示 + show: boolean + // 颜色 + color: string +} + +// 定义组件 +export const component = { + id: 'PromotionPoint', + name: '积分商城', + icon: 'ep:present', + property: { + layoutType: 'oneColBigImg', + fields: { + name: { show: true, color: '#000' }, + introduction: { show: true, color: '#999' }, + price: { show: true, color: '#ff3000' }, + marketPrice: { show: true, color: '#c4c4c4' }, + salesCount: { show: true, color: '#c4c4c4' }, + stock: { show: false, color: '#c4c4c4' } + }, + badge: { show: false, imgUrl: '' }, + btnBuy: { + type: 'text', + text: '立即兑换', + bgBeginColor: '#FF6000', + bgEndColor: '#FE832A', + imgUrl: '' + }, + borderRadiusTop: 8, + borderRadiusBottom: 8, + space: 8, + style: { + bgType: 'color', + bgColor: '', + marginLeft: 8, + marginRight: 8, + marginBottom: 8 + } as ComponentStyle + } +} as DiyComponent diff --git a/src/components/DiyEditor/components/mobile/PromotionPoint/index.vue b/src/components/DiyEditor/components/mobile/PromotionPoint/index.vue new file mode 100644 index 00000000..4acd93fc --- /dev/null +++ b/src/components/DiyEditor/components/mobile/PromotionPoint/index.vue @@ -0,0 +1,202 @@ + + + + diff --git a/src/components/DiyEditor/components/mobile/PromotionPoint/property.vue b/src/components/DiyEditor/components/mobile/PromotionPoint/property.vue new file mode 100644 index 00000000..84a429b6 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/PromotionPoint/property.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/src/components/DiyEditor/components/mobile/PromotionSeckill/config.ts b/src/components/DiyEditor/components/mobile/PromotionSeckill/config.ts index 800398be..022be92c 100644 --- a/src/components/DiyEditor/components/mobile/PromotionSeckill/config.ts +++ b/src/components/DiyEditor/components/mobile/PromotionSeckill/config.ts @@ -3,13 +3,21 @@ import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util' /** 秒杀属性 */ export interface PromotionSeckillProperty { // 布局类型:单列 | 三列 - layoutType: 'oneCol' | 'threeCol' + layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol' // 商品字段 fields: { // 商品名称 name: PromotionSeckillFieldProperty + // 商品简介 + introduction: PromotionSeckillFieldProperty // 商品价格 price: PromotionSeckillFieldProperty + // 市场价 + marketPrice: PromotionSeckillFieldProperty + // 商品销量 + salesCount: PromotionSeckillFieldProperty + // 商品库存 + stock: PromotionSeckillFieldProperty } // 角标 badge: { @@ -18,6 +26,19 @@ export interface PromotionSeckillProperty { // 角标图片 imgUrl: string } + // 按钮 + btnBuy: { + // 类型:文字 | 图片 + type: 'text' | 'img' + // 文字 + text: string + // 文字按钮:背景渐变起始颜色 + bgBeginColor: string + // 文字按钮:背景渐变结束颜色 + bgEndColor: string + // 图片按钮:图片地址 + imgUrl: string + } // 上圆角 borderRadiusTop: number // 下圆角 @@ -25,10 +46,11 @@ export interface PromotionSeckillProperty { // 间距 space: number // 秒杀活动编号 - activityId: number + activityIds: number[] // 组件样式 style: ComponentStyle } + // 商品字段 export interface PromotionSeckillFieldProperty { // 是否显示 @@ -43,13 +65,23 @@ export const component = { name: '秒杀', icon: 'mdi:calendar-time', property: { - activityId: undefined, - layoutType: 'oneCol', + layoutType: 'oneColBigImg', fields: { name: { show: true, color: '#000' }, - price: { show: true, color: '#ff3000' } + introduction: { show: true, color: '#999' }, + price: { show: true, color: '#ff3000' }, + marketPrice: { show: true, color: '#c4c4c4' }, + salesCount: { show: true, color: '#c4c4c4' }, + stock: { show: false, color: '#c4c4c4' } }, badge: { show: false, imgUrl: '' }, + btnBuy: { + type: 'text', + text: '立即秒杀', + bgBeginColor: '#FF6000', + bgEndColor: '#FE832A', + imgUrl: '' + }, borderRadiusTop: 8, borderRadiusBottom: 8, space: 8, diff --git a/src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue b/src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue index fe092a03..3d34a3d4 100644 --- a/src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue +++ b/src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue @@ -1,135 +1,201 @@ - - + diff --git a/src/components/DiyEditor/components/mobile/PromotionSeckill/property.vue b/src/components/DiyEditor/components/mobile/PromotionSeckill/property.vue index 306ec9b9..61287590 100644 --- a/src/components/DiyEditor/components/mobile/PromotionSeckill/property.vue +++ b/src/components/DiyEditor/components/mobile/PromotionSeckill/property.vue @@ -2,30 +2,31 @@ - - - - - + - - + + - + + + + + + + + + + + @@ -34,12 +35,36 @@ + +
+ + +
+
+ +
+ + +
+
+ +
+ + +
+
+ +
+ + +
+
@@ -47,10 +72,36 @@ - + + + + + 文字 + 图片 + + + + + () const emit = defineEmits(['update:modelValue']) const { formData } = usePropertyForm(props.modelValue, emit) // 活动列表 -const activityList = ref([]) +const activityList = ref([]) onMounted(async () => { const { list } = await SeckillActivityApi.getSeckillActivityPage({ status: CommonStatusEnum.ENABLE diff --git a/src/components/DiyEditor/components/mobile/TabBar/property.vue b/src/components/DiyEditor/components/mobile/TabBar/property.vue index b0f7be01..d1da142b 100644 --- a/src/components/DiyEditor/components/mobile/TabBar/property.vue +++ b/src/components/DiyEditor/components/mobile/TabBar/property.vue @@ -79,7 +79,7 @@ diff --git a/src/views/bpm/processInstance/index.vue b/src/views/bpm/processInstance/index.vue index f1d6ca73..4b72e395 100644 --- a/src/views/bpm/processInstance/index.vue +++ b/src/views/bpm/processInstance/index.vue @@ -19,10 +19,10 @@ class="!w-240px" /> - + diff --git a/src/views/infra/webSocket/index.vue b/src/views/infra/webSocket/index.vue index a794344d..37f1322e 100644 --- a/src/views/infra/webSocket/index.vue +++ b/src/views/infra/webSocket/index.vue @@ -71,7 +71,7 @@ diff --git a/src/views/iot/device/detail/DeviceDetailsHeader.vue b/src/views/iot/device/detail/DeviceDetailsHeader.vue new file mode 100644 index 00000000..62960529 --- /dev/null +++ b/src/views/iot/device/detail/DeviceDetailsHeader.vue @@ -0,0 +1,76 @@ + + diff --git a/src/views/iot/device/detail/DeviceDetailsInfo.vue b/src/views/iot/device/detail/DeviceDetailsInfo.vue new file mode 100644 index 00000000..59b9d254 --- /dev/null +++ b/src/views/iot/device/detail/DeviceDetailsInfo.vue @@ -0,0 +1,123 @@ + + diff --git a/src/views/iot/device/detail/index.vue b/src/views/iot/device/detail/index.vue new file mode 100644 index 00000000..2db16bbc --- /dev/null +++ b/src/views/iot/device/detail/index.vue @@ -0,0 +1,66 @@ + + diff --git a/src/views/iot/device/index.vue b/src/views/iot/device/index.vue new file mode 100644 index 00000000..784b1482 --- /dev/null +++ b/src/views/iot/device/index.vue @@ -0,0 +1,267 @@ + + + diff --git a/src/views/iot/product/ProductForm.vue b/src/views/iot/product/ProductForm.vue new file mode 100644 index 00000000..75d6efcc --- /dev/null +++ b/src/views/iot/product/ProductForm.vue @@ -0,0 +1,204 @@ + + + diff --git a/src/views/iot/product/detail/ProductDetailsHeader.vue b/src/views/iot/product/detail/ProductDetailsHeader.vue new file mode 100644 index 00000000..ba009516 --- /dev/null +++ b/src/views/iot/product/detail/ProductDetailsHeader.vue @@ -0,0 +1,103 @@ + + diff --git a/src/views/iot/product/detail/ProductDetailsInfo.vue b/src/views/iot/product/detail/ProductDetailsInfo.vue new file mode 100644 index 00000000..5153045e --- /dev/null +++ b/src/views/iot/product/detail/ProductDetailsInfo.vue @@ -0,0 +1,44 @@ + + diff --git a/src/views/iot/product/detail/ProductTopic.vue b/src/views/iot/product/detail/ProductTopic.vue new file mode 100644 index 00000000..c327bb65 --- /dev/null +++ b/src/views/iot/product/detail/ProductTopic.vue @@ -0,0 +1,243 @@ + + diff --git a/src/views/iot/product/detail/ThinkModelFunction.vue b/src/views/iot/product/detail/ThinkModelFunction.vue new file mode 100644 index 00000000..5a75d109 --- /dev/null +++ b/src/views/iot/product/detail/ThinkModelFunction.vue @@ -0,0 +1,154 @@ + + diff --git a/src/views/iot/product/detail/ThinkModelFunctionForm.vue b/src/views/iot/product/detail/ThinkModelFunctionForm.vue new file mode 100644 index 00000000..895692e0 --- /dev/null +++ b/src/views/iot/product/detail/ThinkModelFunctionForm.vue @@ -0,0 +1,229 @@ + + + diff --git a/src/views/iot/product/detail/index.vue b/src/views/iot/product/detail/index.vue new file mode 100644 index 00000000..ddc5e185 --- /dev/null +++ b/src/views/iot/product/detail/index.vue @@ -0,0 +1,80 @@ + + diff --git a/src/views/iot/product/index.vue b/src/views/iot/product/index.vue new file mode 100644 index 00000000..fa285819 --- /dev/null +++ b/src/views/iot/product/index.vue @@ -0,0 +1,191 @@ + + + diff --git a/src/views/knowledge/dataset-form/form-step1.vue b/src/views/knowledge/dataset-form/form-step1.vue new file mode 100644 index 00000000..ef3579eb --- /dev/null +++ b/src/views/knowledge/dataset-form/form-step1.vue @@ -0,0 +1,151 @@ + + + + + diff --git a/src/views/knowledge/dataset-form/form-step2.vue b/src/views/knowledge/dataset-form/form-step2.vue new file mode 100644 index 00000000..f8ca5718 --- /dev/null +++ b/src/views/knowledge/dataset-form/form-step2.vue @@ -0,0 +1,168 @@ + + + + + diff --git a/src/views/knowledge/dataset.vue b/src/views/knowledge/dataset.vue new file mode 100644 index 00000000..4636a912 --- /dev/null +++ b/src/views/knowledge/dataset.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/src/views/mall/product/property/value/index.vue b/src/views/mall/product/property/value/index.vue index d708172c..f0a6ef48 100644 --- a/src/views/mall/product/property/value/index.vue +++ b/src/views/mall/product/property/value/index.vue @@ -105,7 +105,7 @@ const list = ref([]) // 列表的数据 const queryParams = reactive({ pageNo: 1, pageSize: 10, - propertyId: Number(params.propertyId), + propertyId: params.propertyId, name: undefined }) const queryFormRef = ref() // 搜索的表单 diff --git a/src/views/mall/product/spu/components/SkuList.vue b/src/views/mall/product/spu/components/SkuList.vue index 25475cf8..2ffb37d0 100644 --- a/src/views/mall/product/spu/components/SkuList.vue +++ b/src/views/mall/product/spu/components/SkuList.vue @@ -180,17 +180,17 @@ @@ -211,12 +211,12 @@ diff --git a/src/views/mall/product/spu/form/InfoForm.vue b/src/views/mall/product/spu/form/InfoForm.vue index 76a09706..28bd309b 100644 --- a/src/views/mall/product/spu/form/InfoForm.vue +++ b/src/views/mall/product/spu/form/InfoForm.vue @@ -45,7 +45,7 @@ :show-word-limit="true" class="w-80!" maxlength="128" - placeholder="请输入商品名称" + placeholder="请输入商品简介" type="textarea" /> diff --git a/src/views/mall/promotion/combination/activity/index.vue b/src/views/mall/promotion/combination/activity/index.vue index 02c7de22..a40044df 100644 --- a/src/views/mall/promotion/combination/activity/index.vue +++ b/src/views/mall/promotion/combination/activity/index.vue @@ -4,27 +4,27 @@ - 搜索 - 重置 + + + 搜索 + + + + 重置 + - 新增 + + 新增 @@ -51,77 +58,77 @@ - - - + + + - + - + - + - - - - + + + + - + - diff --git a/src/views/mall/promotion/point/activity/index.vue b/src/views/mall/promotion/point/activity/index.vue new file mode 100644 index 00000000..ceceb7b5 --- /dev/null +++ b/src/views/mall/promotion/point/activity/index.vue @@ -0,0 +1,219 @@ + + + diff --git a/src/views/mall/promotion/point/activity/pointActivity.data.ts b/src/views/mall/promotion/point/activity/pointActivity.data.ts new file mode 100644 index 00000000..a3334eac --- /dev/null +++ b/src/views/mall/promotion/point/activity/pointActivity.data.ts @@ -0,0 +1,55 @@ +import type { CrudSchema } from '@/hooks/web/useCrudSchemas' + +// 表单校验 +export const rules = reactive({ + spuId: [required], + sort: [required] +}) + +// CrudSchema https://doc.iocoder.cn/vue3/crud-schema/ +const crudSchemas = reactive([ + { + label: '排序', + field: 'sort', + form: { + component: 'InputNumber', + value: 0 + }, + table: { + width: 80 + } + }, + { + label: '积分商城活动商品', + field: 'spuId', + isTable: true, + isSearch: false, + form: { + colProps: { + span: 24 + } + }, + table: { + width: 300 + } + }, + { + label: '备注', + field: 'remark', + isSearch: false, + form: { + component: 'Input', + componentProps: { + type: 'textarea', + rows: 4 + }, + colProps: { + span: 24 + } + }, + table: { + width: 300 + } + } +]) +export const { allSchemas } = useCrudSchemas(crudSchemas) diff --git a/src/views/mall/promotion/point/components/PointShowcase.vue b/src/views/mall/promotion/point/components/PointShowcase.vue new file mode 100644 index 00000000..82e490c5 --- /dev/null +++ b/src/views/mall/promotion/point/components/PointShowcase.vue @@ -0,0 +1,154 @@ + + + + diff --git a/src/views/mall/promotion/point/components/PointTableSelect.vue b/src/views/mall/promotion/point/components/PointTableSelect.vue new file mode 100644 index 00000000..d68b5f15 --- /dev/null +++ b/src/views/mall/promotion/point/components/PointTableSelect.vue @@ -0,0 +1,300 @@ + + + diff --git a/src/views/mall/promotion/rewardActivity/RewardForm.vue b/src/views/mall/promotion/rewardActivity/RewardForm.vue index fc1d5dfc..64a2dd4a 100644 --- a/src/views/mall/promotion/rewardActivity/RewardForm.vue +++ b/src/views/mall/promotion/rewardActivity/RewardForm.vue @@ -56,7 +56,7 @@ label="分类" prop="productCategoryIds" > - + @@ -119,6 +119,9 @@ const open = async (type: string, id?: number) => { // 规则分转元 data.rules?.forEach((item: any) => { item.discountPrice = fenToYuan(item.discountPrice || 0) + if (data.conditionType === PromotionConditionTypeEnum.PRICE.type) { + item.limit = fenToYuan(item.limit || 0) + } }) formData.value = data // 获得商品范围 @@ -151,6 +154,9 @@ const submitForm = async () => { // 规则元转分 data.rules.forEach((item) => { item.discountPrice = yuanToFen(item.discountPrice || 0) + if (data.conditionType === PromotionConditionTypeEnum.PRICE.type) { + item.limit = yuanToFen(item.limit || 0) + } }) // 设置商品范围 setProductScopeValues(data) @@ -188,7 +194,7 @@ const getProductScope = async () => { case PromotionProductScopeEnum.CATEGORY.scope: await nextTick() let productCategoryIds = formData.value.productScopeValues as any - if (Array.isArray(productCategoryIds) && productCategoryIds.length > 0) { + if (Array.isArray(productCategoryIds) && productCategoryIds.length === 1) { // 单选时使用数组不能反显 productCategoryIds = productCategoryIds[0] } diff --git a/src/views/mall/promotion/rewardActivity/components/RewardRule.vue b/src/views/mall/promotion/rewardActivity/components/RewardRule.vue index 8dc37b32..2c63a427 100644 --- a/src/views/mall/promotion/rewardActivity/components/RewardRule.vue +++ b/src/views/mall/promotion/rewardActivity/components/RewardRule.vue @@ -10,14 +10,25 @@ 满 + - {{ PromotionConditionTypeEnum.PRICE.type === formData.conditionType ? '元' : '件' }} diff --git a/src/views/mall/promotion/rewardActivity/components/RewardRuleCouponSelect.vue b/src/views/mall/promotion/rewardActivity/components/RewardRuleCouponSelect.vue index f515e4f1..ccadd0b9 100644 --- a/src/views/mall/promotion/rewardActivity/components/RewardRuleCouponSelect.vue +++ b/src/views/mall/promotion/rewardActivity/components/RewardRuleCouponSelect.vue @@ -1,5 +1,5 @@