- 完成扫码登录的功能

This commit is contained in:
2025-09-21 08:44:44 +08:00
parent 1ba4367c6f
commit 85206f3894
120 changed files with 53 additions and 16971 deletions

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsDocs, CmsDocsParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询文档管理记录表
*/
export async function pageCmsDocs(params: CmsDocsParam) {
const res = await request.get<ApiResult<PageResult<CmsDocs>>>(
MODULES_API_URL + '/cms/cms-docs/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询文档管理记录表列表
*/
export async function listCmsDocs(params?: CmsDocsParam) {
const res = await request.get<ApiResult<CmsDocs[]>>(
MODULES_API_URL + '/cms/cms-docs',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加文档管理记录表
*/
export async function addCmsDocs(data: CmsDocs) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改文档管理记录表
*/
export async function updateCmsDocs(data: CmsDocs) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除文档管理记录表
*/
export async function removeCmsDocs(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除文档管理记录表
*/
export async function removeBatchCmsDocs(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询文档管理记录表
*/
export async function getCmsDocs(id: number) {
const res = await request.get<ApiResult<CmsDocs>>(
MODULES_API_URL + '/cms/cms-docs/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,45 +0,0 @@
import type { PageParam } from '@/api';
/**
* 文档管理记录表
*/
export interface CmsDocs {
// 文档ID
docsId?: number;
// 文档标题
title?: string;
// 上级目录
parentId?: number;
// 书籍ID
bookId?: number;
// 可见性(public,private,protected)
visibility?: string;
// 虚拟阅读量(仅用作展示)
virtualViews?: number;
// 实际阅读量
actualViews?: number;
// 用户ID
userId?: number;
// 备注
comments?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 文档管理记录表搜索条件
*/
export interface CmsDocsParam extends PageParam {
docsId?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsDocsBook, CmsDocsBookParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询书籍记录表
*/
export async function pageCmsDocsBook(params: CmsDocsBookParam) {
const res = await request.get<ApiResult<PageResult<CmsDocsBook>>>(
MODULES_API_URL + '/cms/cms-docs-book/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询书籍记录表列表
*/
export async function listCmsDocsBook(params?: CmsDocsBookParam) {
const res = await request.get<ApiResult<CmsDocsBook[]>>(
MODULES_API_URL + '/cms/cms-docs-book',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加书籍记录表
*/
export async function addCmsDocsBook(data: CmsDocsBook) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs-book',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改书籍记录表
*/
export async function updateCmsDocsBook(data: CmsDocsBook) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs-book',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除书籍记录表
*/
export async function removeCmsDocsBook(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs-book/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除书籍记录表
*/
export async function removeBatchCmsDocsBook(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs-book/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询书籍记录表
*/
export async function getCmsDocsBook(id: number) {
const res = await request.get<ApiResult<CmsDocsBook>>(
MODULES_API_URL + '/cms/cms-docs-book/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,37 +0,0 @@
import type { PageParam } from '@/api';
/**
* 书籍记录表
*/
export interface CmsDocsBook {
// ID
bookId?: number;
// 书籍名称
name?: string;
// 书籍标识
code?: string;
// 封面图
photo?: string;
// 备注
comments?: string;
// 文档内容
content?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 书籍记录表搜索条件
*/
export interface CmsDocsBookParam extends PageParam {
bookId?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsDocsContent, CmsDocsContentParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询文档内容记录表
*/
export async function pageCmsDocsContent(params: CmsDocsContentParam) {
const res = await request.get<ApiResult<PageResult<CmsDocsContent>>>(
MODULES_API_URL + '/cms/cms-docs-content/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询文档内容记录表列表
*/
export async function listCmsDocsContent(params?: CmsDocsContentParam) {
const res = await request.get<ApiResult<CmsDocsContent[]>>(
MODULES_API_URL + '/cms/cms-docs-content',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加文档内容记录表
*/
export async function addCmsDocsContent(data: CmsDocsContent) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs-content',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改文档内容记录表
*/
export async function updateCmsDocsContent(data: CmsDocsContent) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs-content',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除文档内容记录表
*/
export async function removeCmsDocsContent(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs-content/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除文档内容记录表
*/
export async function removeBatchCmsDocsContent(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-docs-content/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询文档内容记录表
*/
export async function getCmsDocsContent(id: number) {
const res = await request.get<ApiResult<CmsDocsContent>>(
MODULES_API_URL + '/cms/cms-docs-content/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,25 +0,0 @@
import type { PageParam } from '@/api';
/**
* 文档内容记录表
*/
export interface CmsDocsContent {
// ID
id?: number;
// 文档ID
docsId?: number;
// 文档内容
content?: string;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 文档内容记录表搜索条件
*/
export interface CmsDocsContentParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsMp, CmsMpParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询小程序信息
*/
export async function pageCmsMp(params: CmsMpParam) {
const res = await request.get<ApiResult<PageResult<CmsMp>>>(
MODULES_API_URL + '/cms/cms-mp/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询小程序信息列表
*/
export async function listCmsMp(params?: CmsMpParam) {
const res = await request.get<ApiResult<CmsMp[]>>(
MODULES_API_URL + '/cms/cms-mp',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加小程序信息
*/
export async function addCmsMp(data: CmsMp) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改小程序信息
*/
export async function updateCmsMp(data: CmsMp) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除小程序信息
*/
export async function removeCmsMp(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除小程序信息
*/
export async function removeBatchCmsMp(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询小程序信息
*/
export async function getCmsMp(id: number) {
const res = await request.get<ApiResult<CmsMp>>(
MODULES_API_URL + '/cms/cms-mp/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,61 +0,0 @@
import type { PageParam } from '@/api';
/**
* 小程序信息
*/
export interface CmsMp {
// ID
mpId?: number;
// 是否主账号
type?: number;
// 小程序ID
appId?: string;
// 小程序密钥
appSecret?: string;
// 小程序名称
mpName?: string;
// 小程序简称
shortName?: string;
// 头像
avatar?: string;
// 小程序码
mpQrcode?: string;
// 微信认证
authentication?: number;
// 主体信息
companyName?: string;
// 小程序备案
icpNo?: string;
// 登录邮箱
email?: string;
// 登录密码
password?: string;
// 原始ID
ghId?: string;
// 入口页面
mainPath?: string;
// 过期时间
expirationTime?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 介绍
comments?: string;
// 用户ID
userId?: number;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 小程序信息搜索条件
*/
export interface CmsMpParam extends PageParam {
mpId?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsMpAd, CmsMpAdParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询小程序广告位
*/
export async function pageCmsMpAd(params: CmsMpAdParam) {
const res = await request.get<ApiResult<PageResult<CmsMpAd>>>(
MODULES_API_URL + '/cms/cms-mp-ad/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询小程序广告位列表
*/
export async function listCmsMpAd(params?: CmsMpAdParam) {
const res = await request.get<ApiResult<CmsMpAd[]>>(
MODULES_API_URL + '/cms/cms-mp-ad',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加小程序广告位
*/
export async function addCmsMpAd(data: CmsMpAd) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-ad',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改小程序广告位
*/
export async function updateCmsMpAd(data: CmsMpAd) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-ad',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除小程序广告位
*/
export async function removeCmsMpAd(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-ad/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除小程序广告位
*/
export async function removeBatchCmsMpAd(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-ad/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询小程序广告位
*/
export async function getCmsMpAd(id: number) {
const res = await request.get<ApiResult<CmsMpAd>>(
MODULES_API_URL + '/cms/cms-mp-ad/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,47 +0,0 @@
import type { PageParam } from '@/api';
/**
* 小程序广告位
*/
export interface CmsMpAd {
// ID
adId?: number;
// 页面ID
pageId?: number;
// 广告类型
adType?: string;
// 广告位名称
name?: string;
// 宽
width?: string;
// 高
height?: string;
// 广告图片
images?: string;
// 路由/链接地址
path?: string;
// 页面名称
pageName?: string;
// 用户ID
userId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 小程序广告位搜索条件
*/
export interface CmsMpAdParam extends PageParam {
adId?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsMpField, CmsMpFieldParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询小程序配置
*/
export async function pageCmsMpField(params: CmsMpFieldParam) {
const res = await request.get<ApiResult<PageResult<CmsMpField>>>(
MODULES_API_URL + '/cms/cms-mp-field/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询小程序配置列表
*/
export async function listCmsMpField(params?: CmsMpFieldParam) {
const res = await request.get<ApiResult<CmsMpField[]>>(
MODULES_API_URL + '/cms/cms-mp-field',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加小程序配置
*/
export async function addCmsMpField(data: CmsMpField) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-field',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改小程序配置
*/
export async function updateCmsMpField(data: CmsMpField) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-field',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除小程序配置
*/
export async function removeCmsMpField(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-field/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除小程序配置
*/
export async function removeBatchCmsMpField(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-field/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询小程序配置
*/
export async function getCmsMpField(id: number) {
const res = await request.get<ApiResult<CmsMpField>>(
MODULES_API_URL + '/cms/cms-mp-field/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,35 +0,0 @@
import type { PageParam } from '@/api';
/**
* 小程序配置
*/
export interface CmsMpField {
// 自增ID
id?: number;
// 类型0文本 1图片 2其他
type?: number;
// 名称
name?: string;
// 备注
comments?: string;
// 名称
value?: string;
// 页面ID
pageId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 小程序配置搜索条件
*/
export interface CmsMpFieldParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsMpMenu, CmsMpMenuParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询小程序端菜单
*/
export async function pageCmsMpMenu(params: CmsMpMenuParam) {
const res = await request.get<ApiResult<PageResult<CmsMpMenu>>>(
MODULES_API_URL + '/cms/cms-mp-menu/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询小程序端菜单列表
*/
export async function listCmsMpMenu(params?: CmsMpMenuParam) {
const res = await request.get<ApiResult<CmsMpMenu[]>>(
MODULES_API_URL + '/cms/cms-mp-menu',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加小程序端菜单
*/
export async function addCmsMpMenu(data: CmsMpMenu) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-menu',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改小程序端菜单
*/
export async function updateCmsMpMenu(data: CmsMpMenu) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-menu',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除小程序端菜单
*/
export async function removeCmsMpMenu(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-menu/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除小程序端菜单
*/
export async function removeBatchCmsMpMenu(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-menu/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询小程序端菜单
*/
export async function getCmsMpMenu(id: number) {
const res = await request.get<ApiResult<CmsMpMenu>>(
MODULES_API_URL + '/cms/cms-mp-menu/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,79 +0,0 @@
import type { PageParam } from '@/api';
/**
* 小程序端菜单
*/
export interface CmsMpMenu {
// ID
menuId?: number;
// 上级id, 0是顶级
parentId?: number;
// 菜单名称
title?: string;
// 类型 0功能图标 1订单状态图标 2首页导航图标 3 商城导航图标 4管理人员功能图标
type?: number;
// 是否微信小程序菜单
isMpWeixin?: string;
// 菜单路由地址
path?: string;
// 菜单组件地址, 目录可为空
component?: string;
// 打开位置
target?: string;
// 菜单图标
avatar?: string;
// 图标颜色
color?: string;
// 上传图标
icon?: string;
// 是否隐藏, 0否, 1是(仅注册路由不显示在左侧菜单)
hide?: number;
// 位置 0不限 1顶部 2底部
position?: number;
// 0 第一行 1第二行
rows?: number;
// 菜单侧栏选中的path
active?: string;
// 其它路由元信息
meta?: string;
// 绑定的页面
pageId?: number;
// 绑定的文章分类ID
articleCategoryId?: number;
// 绑定的文章ID
articleId?: number;
// 绑定的表单ID
formId?: number;
// 绑定的书籍标识
bookCode?: string;
// 绑定的商品分类ID
goodsCategoryId?: number;
// 绑定的商品ID
goodsId?: number;
// 用户ID
userId?: number;
// 是否管理人员可见
adminShow?: number;
// 设为首页
home?: number;
// 分组名称
groupName?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 小程序端菜单搜索条件
*/
export interface CmsMpMenuParam extends PageParam {
menuId?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsMpOfficialMenu, CmsMpOfficialMenuParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询微信公众号
*/
export async function pageCmsMpOfficialMenu(params: CmsMpOfficialMenuParam) {
const res = await request.get<ApiResult<PageResult<CmsMpOfficialMenu>>>(
MODULES_API_URL + '/cms/cms-mp-official-menu/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询微信公众号列表
*/
export async function listCmsMpOfficialMenu(params?: CmsMpOfficialMenuParam) {
const res = await request.get<ApiResult<CmsMpOfficialMenu[]>>(
MODULES_API_URL + '/cms/cms-mp-official-menu',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加微信公众号
*/
export async function addCmsMpOfficialMenu(data: CmsMpOfficialMenu) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-official-menu',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改微信公众号
*/
export async function updateCmsMpOfficialMenu(data: CmsMpOfficialMenu) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-official-menu',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除微信公众号
*/
export async function removeCmsMpOfficialMenu(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-official-menu/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除微信公众号
*/
export async function removeBatchCmsMpOfficialMenu(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-official-menu/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询微信公众号
*/
export async function getCmsMpOfficialMenu(id: number) {
const res = await request.get<ApiResult<CmsMpOfficialMenu>>(
MODULES_API_URL + '/cms/cms-mp-official-menu/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,35 +0,0 @@
import type { PageParam } from '@/api';
/**
* 微信公众号
*/
export interface CmsMpOfficialMenu {
// ID
id?: number;
// 上级id, 0是顶级
parentId?: number;
// 菜单名称
name?: string;
// 类型
type?: string;
// 菜单值
key?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 微信公众号搜索条件
*/
export interface CmsMpOfficialMenuParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsMpPages, CmsMpPagesParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询小程序页面
*/
export async function pageCmsMpPages(params: CmsMpPagesParam) {
const res = await request.get<ApiResult<PageResult<CmsMpPages>>>(
MODULES_API_URL + '/cms/cms-mp-pages/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询小程序页面列表
*/
export async function listCmsMpPages(params?: CmsMpPagesParam) {
const res = await request.get<ApiResult<CmsMpPages[]>>(
MODULES_API_URL + '/cms/cms-mp-pages',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加小程序页面
*/
export async function addCmsMpPages(data: CmsMpPages) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-pages',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改小程序页面
*/
export async function updateCmsMpPages(data: CmsMpPages) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-pages',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除小程序页面
*/
export async function removeCmsMpPages(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-pages/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除小程序页面
*/
export async function removeBatchCmsMpPages(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-mp-pages/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询小程序页面
*/
export async function getCmsMpPages(id: number) {
const res = await request.get<ApiResult<CmsMpPages>>(
MODULES_API_URL + '/cms/cms-mp-pages/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,49 +0,0 @@
import type { PageParam } from '@/api';
/**
* 小程序页面
*/
export interface CmsMpPages {
// ID
id?: number;
// 上级id, 0是顶级
parentId?: number;
// 页面名称
title?: string;
// 页面路径
path?: string;
// 设为首页
home?: number;
// 分包
subpackage?: string;
// 图标
icon?: string;
// 未选中图标
iconPath?: string;
// 选中的图标
selectedIconPath?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 用户ID
userId?: number;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 子级
children?: CmsMpPages[];
}
/**
* 小程序页面搜索条件
*/
export interface CmsMpPagesParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -1,116 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsProduct, CmsProductParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询产品
*/
export async function pageCmsProduct(params: CmsProductParam) {
const res = await request.get<ApiResult<PageResult<CmsProduct>>>(
MODULES_API_URL + '/cms/cms-product/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询产品列表
*/
export async function listCmsProduct(params?: CmsProductParam) {
const res = await request.get<ApiResult<CmsProduct[]>>(
MODULES_API_URL + '/cms/cms-product',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加产品
*/
export async function addCmsProduct(data: CmsProduct) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改产品
*/
export async function updateCmsProduct(data: CmsProduct) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除产品
*/
export async function removeCmsProduct(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除产品
*/
export async function removeBatchCmsProduct(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询产品
*/
export async function getCmsProduct(id: number) {
const res = await request.get<ApiResult<CmsProduct>>(
MODULES_API_URL + '/cms/cms-product/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
export async function getCount(params: CmsProductParam) {
const res = await request.get(MODULES_API_URL + '/cms/cms-product/data', {
params
});
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,98 +0,0 @@
import type { PageParam } from '@/api';
/**
* 产品
*/
export interface CmsProduct {
// 自增ID
productId?: number;
// 类型 0软件产品 1实物商品 2虚拟商品
type?: number;
// 产品编码
code?: string;
// 产品标题
title?: string;
// 封面图
image?: string;
// 产品详情
content?: string;
// 父级分类ID
parentId?: number;
// 父级栏目名称
parentName?: string;
// 产品分类ID
categoryId?: number;
// 分类名称
categoryName?: string;
// 关联的菜单ID
menuId?: number;
// 控制台入口
path?: string;
// 产品规格 0单规格 1多规格
specs?: number;
// 货架
position?: string;
// 单位名称 (个)
unitName?: string;
// 进货价格
price?: string;
// 销售价格
salePrice?: string;
// 标签
tag?: string;
// 库存计算方式(10下单减库存 20付款减库存)
deductStockType?: number;
// 交付方式
deliveryMethod?: number;
// 购买时长
durationMethod?: number;
// 服务套餐
serverMethod?: number;
// 套餐版本
packageMethod?: number;
// 可购买数量
canBuyNumber?: number;
// 轮播图
files?: string;
// 销量
sales?: number;
// 库存
stock?: number;
// 消费赚取积分
gainIntegral?: string;
// 推荐
recommend?: number;
// 是否官方自营
official?: number;
// 商户ID
merchantId?: number;
// 状态0未上架1上架
isShow?: string;
// 状态, 0上架 1待上架 2待审核 3审核不通过
status?: number;
// 备注
comments?: string;
// 排序号
sortNumber?: number;
// 用户ID
userId?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 产品搜索条件
*/
export interface CmsProductParam extends PageParam {
productId?: number;
type?: number;
official?: number;
status?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type {ApiResult, PageResult} from '@/api';
import type {CmsProductComment, CmsProductCommentParam} from './model';
import {MODULES_API_URL} from '@/config/setting';
/**
* 分页查询产品评论
*/
export async function pageCmsProductComment(params: CmsProductCommentParam) {
const res = await request.get<ApiResult<PageResult<CmsProductComment>>>(
MODULES_API_URL + '/cms/cms-product-comment/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询产品评论列表
*/
export async function listCmsProductComment(params?: CmsProductCommentParam) {
const res = await request.get<ApiResult<CmsProductComment[]>>(
MODULES_API_URL + '/cms/cms-product-comment',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加产品评论
*/
export async function addCmsProductComment(data: CmsProductComment) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-comment',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改产品评论
*/
export async function updateCmsProductComment(data: CmsProductComment) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-comment',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除产品评论
*/
export async function removeCmsProductComment(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-comment/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除产品评论
*/
export async function removeBatchCmsProductComment(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-comment/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询产品评论
*/
export async function getCmsProductComment(id: number) {
const res = await request.get<ApiResult<CmsProductComment>>(
MODULES_API_URL + '/cms/cms-product-comment/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,37 +0,0 @@
import type { PageParam } from '@/api';
/**
* 产品评论
*/
export interface CmsProductComment {
// ID
id?: number;
// 产品ID
productId?: number;
// 用户ID
userId?: number;
// 昵称
nickname?: string;
// 用户头像
avatar?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 评论内容
comments?: string;
// 状态
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
image?: string;
}
/**
* 产品评论搜索条件
*/
export interface CmsProductCommentParam extends PageParam {
id?: number;
userId?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsProductParameter, CmsProductParameterParam } from './model';
import {MODULES_API_URL} from '@/config/setting';
/**
* 分页查询产品参数
*/
export async function pageCmsProductParameter(params: CmsProductParameterParam) {
const res = await request.get<ApiResult<PageResult<CmsProductParameter>>>(
MODULES_API_URL + '/cms/cms-product-parameter/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询产品参数列表
*/
export async function listCmsProductParameter(params?: CmsProductParameterParam) {
const res = await request.get<ApiResult<CmsProductParameter[]>>(
MODULES_API_URL + '/cms/cms-product-parameter',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加产品参数
*/
export async function addCmsProductParameter(data: CmsProductParameter) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-parameter',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改产品参数
*/
export async function updateCmsProductParameter(data: CmsProductParameter) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-parameter',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除产品参数
*/
export async function removeCmsProductParameter(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-parameter/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除产品参数
*/
export async function removeBatchCmsProductParameter(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-parameter/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询产品参数
*/
export async function getCmsProductParameter(id: number) {
const res = await request.get<ApiResult<CmsProductParameter>>(
MODULES_API_URL + '/cms/cms-product-parameter/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,33 +0,0 @@
import type { PageParam } from '@/api';
/**
* 产品参数
*/
export interface CmsProductParameter {
// 自增ID
id?: number;
// 产品ID
productId?: number;
// 参数名称
name?: string;
// 参数内容
value?: string;
// 备注
comments?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 状态, 0正常, 1待确认
status?: number;
// 创建时间
createTime?: string;
// 租户id
tenantId?: number;
}
/**
* 产品参数搜索条件
*/
export interface CmsProductParameterParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsProductRecord, CmsProductRecordParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询插件安装明细
*/
export async function pageCmsProductRecord(params: CmsProductRecordParam) {
const res = await request.get<ApiResult<PageResult<CmsProductRecord>>>(
MODULES_API_URL + '/cms/cms-product-record/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询插件安装明细列表
*/
export async function listCmsProductRecord(params?: CmsProductRecordParam) {
const res = await request.get<ApiResult<CmsProductRecord[]>>(
MODULES_API_URL + '/cms/cms-product-record',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加插件安装明细
*/
export async function addCmsProductRecord(data: CmsProductRecord) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-record',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改插件安装明细
*/
export async function updateCmsProductRecord(data: CmsProductRecord) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-record',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除插件安装明细
*/
export async function removeCmsProductRecord(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-record/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除插件安装明细
*/
export async function removeBatchCmsProductRecord(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-record/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询插件安装明细
*/
export async function getCmsProductRecord(id: number) {
const res = await request.get<ApiResult<CmsProductRecord>>(
MODULES_API_URL + '/cms/cms-product-record/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,31 +0,0 @@
import type { PageParam } from '@/api';
/**
* 插件安装明细
*/
export interface CmsProductRecord {
// ID
id?: number;
// 产品ID
productId?: number;
// 用户ID
userId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0已安装, 1已卸载
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 插件安装明细搜索条件
*/
export interface CmsProductRecordParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsProductSku, CmsProductSkuParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询商品sku列表
*/
export async function pageCmsProductSku(params: CmsProductSkuParam) {
const res = await request.get<ApiResult<PageResult<CmsProductSku>>>(
MODULES_API_URL + '/cms/cms-product-sku/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询商品sku列表列表
*/
export async function listCmsProductSku(params?: CmsProductSkuParam) {
const res = await request.get<ApiResult<CmsProductSku[]>>(
MODULES_API_URL + '/cms/cms-product-sku',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加商品sku列表
*/
export async function addCmsProductSku(data: CmsProductSku) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-sku',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改商品sku列表
*/
export async function updateCmsProductSku(data: CmsProductSku) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-sku',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除商品sku列表
*/
export async function removeCmsProductSku(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-sku/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除商品sku列表
*/
export async function removeBatchCmsProductSku(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-sku/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询商品sku列表
*/
export async function getCmsProductSku(id: number) {
const res = await request.get<ApiResult<CmsProductSku>>(
MODULES_API_URL + '/cms/cms-product-sku/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,49 +0,0 @@
import type { PageParam } from '@/api';
/**
* 商品sku列表
*/
export interface CmsProductSku {
// 主键ID
id?: number;
// 商品ID
goodsId?: number;
// 商品属性索引值 (attr_value|attr_value[|....])
sku?: string;
// 商品图片
image?: string;
// 商品价格
price?: string;
// 市场价格
salePrice?: string;
// 成本价
cost?: string;
// 库存
stock?: number;
// sku编码
skuNo?: string;
// 商品条码
barCode?: string;
// 重量
weight?: string;
// 体积
volume?: string;
// 唯一值
uuid?: string;
// 状态, 0正常, 1异常
status?: number;
// 备注
comments?: string;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 商品sku列表搜索条件
*/
export interface CmsProductSkuParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsProductSpec, CmsProductSpecParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询规格
*/
export async function pageCmsProductSpec(params: CmsProductSpecParam) {
const res = await request.get<ApiResult<PageResult<CmsProductSpec>>>(
MODULES_API_URL + '/cms/cms-product-spec/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询规格列表
*/
export async function listCmsProductSpec(params?: CmsProductSpecParam) {
const res = await request.get<ApiResult<CmsProductSpec[]>>(
MODULES_API_URL + '/cms/cms-product-spec',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加规格
*/
export async function addCmsProductSpec(data: CmsProductSpec) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-spec',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改规格
*/
export async function updateCmsProductSpec(data: CmsProductSpec) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-spec',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除规格
*/
export async function removeCmsProductSpec(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-spec/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除规格
*/
export async function removeBatchCmsProductSpec(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-spec/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询规格
*/
export async function getCmsProductSpec(id: number) {
const res = await request.get<ApiResult<CmsProductSpec>>(
MODULES_API_URL + '/cms/cms-product-spec/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,35 +0,0 @@
import type { PageParam } from '@/api';
/**
* 规格
*/
export interface CmsProductSpec {
// 规格ID
specId?: number;
// 规格名称
specName?: string;
// 规格值
specValue?: string;
// 创建用户
userId?: number;
// 更新者
updater?: number;
// 备注
comments?: string;
// 状态, 0正常, 1待修,2异常已修3异常未修
status?: number;
// 排序号
sortNumber?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 规格搜索条件
*/
export interface CmsProductSpecParam extends PageParam {
specId?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsProductSpecValue, CmsProductSpecValueParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询规格值
*/
export async function pageCmsProductSpecValue(params: CmsProductSpecValueParam) {
const res = await request.get<ApiResult<PageResult<CmsProductSpecValue>>>(
MODULES_API_URL + '/cms/cms-product-spec-value/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询规格值列表
*/
export async function listCmsProductSpecValue(params?: CmsProductSpecValueParam) {
const res = await request.get<ApiResult<CmsProductSpecValue[]>>(
MODULES_API_URL + '/cms/cms-product-spec-value',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加规格值
*/
export async function addCmsProductSpecValue(data: CmsProductSpecValue) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-spec-value',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改规格值
*/
export async function updateCmsProductSpecValue(data: CmsProductSpecValue) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-spec-value',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除规格值
*/
export async function removeCmsProductSpecValue(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-spec-value/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除规格值
*/
export async function removeBatchCmsProductSpecValue(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-spec-value/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询规格值
*/
export async function getCmsProductSpecValue(id: number) {
const res = await request.get<ApiResult<CmsProductSpecValue>>(
MODULES_API_URL + '/cms/cms-product-spec-value/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,29 +0,0 @@
import type { PageParam } from '@/api';
/**
* 规格值
*/
export interface CmsProductSpecValue {
// 规格值ID
specValueId?: number;
// 规格组ID
specId?: number;
// 规格值
specValue?: string;
// 备注
comments?: string;
// 排序号
sortNumber?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 规格值搜索条件
*/
export interface CmsProductSpecValueParam extends PageParam {
specValueId?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type {ApiResult, PageResult} from '@/api';
import type {CmsProductUrl, CmsProductUrlParam} from './model';
import {MODULES_API_URL} from '@/config/setting';
/**
* 分页查询域名
*/
export async function pageCmsProductUrl(params: CmsProductUrlParam) {
const res = await request.get<ApiResult<PageResult<CmsProductUrl>>>(
MODULES_API_URL + '/cms/cms-product-url/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询域名列表
*/
export async function listCmsProductUrl(params?: CmsProductUrlParam) {
const res = await request.get<ApiResult<CmsProductUrl[]>>(
MODULES_API_URL + '/cms/cms-product-url',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加域名
*/
export async function addCmsProductUrl(data: CmsProductUrl) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-url',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改域名
*/
export async function updateCmsProductUrl(data: CmsProductUrl) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-url',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除域名
*/
export async function removeCmsProductUrl(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-url/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除域名
*/
export async function removeBatchCmsProductUrl(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-product-url/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询域名
*/
export async function getCmsProductUrl(id: number) {
const res = await request.get<ApiResult<CmsProductUrl>>(
MODULES_API_URL + '/cms/cms-product-url/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,41 +0,0 @@
import type { PageParam } from '@/api';
/**
* 域名
*/
export interface CmsProductUrl {
// 自增ID
id?: number;
// 产品ID
productId?: number;
// 域名类型
type?: string;
// 域名
domain?: string;
// 账号
account?: string;
// 密码
password?: string;
// 商户ID
merchantId?: number;
// 二维码
qrcode?: string;
// 备注
comments?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 状态, 0正常, 1待确认
status?: number;
// 创建时间
createTime?: string;
// 租户id
tenantId?: number;
}
/**
* 域名搜索条件
*/
export interface CmsProductUrlParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsSpec, CmsSpecParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询规格
*/
export async function pageCmsSpec(params: CmsSpecParam) {
const res = await request.get<ApiResult<PageResult<CmsSpec>>>(
MODULES_API_URL + '/cms/cms-spec/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询规格列表
*/
export async function listCmsSpec(params?: CmsSpecParam) {
const res = await request.get<ApiResult<CmsSpec[]>>(
MODULES_API_URL + '/cms/cms-spec',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加规格
*/
export async function addCmsSpec(data: CmsSpec) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-spec',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改规格
*/
export async function updateCmsSpec(data: CmsSpec) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-spec',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除规格
*/
export async function removeCmsSpec(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-spec/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除规格
*/
export async function removeBatchCmsSpec(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-spec/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询规格
*/
export async function getCmsSpec(id: number) {
const res = await request.get<ApiResult<CmsSpec>>(
MODULES_API_URL + '/cms/cms-spec/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,35 +0,0 @@
import type { PageParam } from '@/api';
/**
* 规格
*/
export interface CmsSpec {
// 规格ID
specId?: number;
// 规格名称
specName?: string;
// 规格值
specValue?: string;
// 创建用户
userId?: number;
// 更新者
updater?: number;
// 备注
comments?: string;
// 状态, 0正常, 1待修,2异常已修3异常未修
status?: number;
// 排序号
sortNumber?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 规格搜索条件
*/
export interface CmsSpecParam extends PageParam {
specId?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsSpecValue, CmsSpecValueParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询规格值
*/
export async function pageCmsSpecValue(params: CmsSpecValueParam) {
const res = await request.get<ApiResult<PageResult<CmsSpecValue>>>(
MODULES_API_URL + '/cms/cms-spec-value/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询规格值列表
*/
export async function listCmsSpecValue(params?: CmsSpecValueParam) {
const res = await request.get<ApiResult<CmsSpecValue[]>>(
MODULES_API_URL + '/cms/cms-spec-value',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加规格值
*/
export async function addCmsSpecValue(data: CmsSpecValue) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-spec-value',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改规格值
*/
export async function updateCmsSpecValue(data: CmsSpecValue) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-spec-value',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除规格值
*/
export async function removeCmsSpecValue(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-spec-value/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除规格值
*/
export async function removeBatchCmsSpecValue(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/cms-spec-value/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询规格值
*/
export async function getCmsSpecValue(id: number) {
const res = await request.get<ApiResult<CmsSpecValue>>(
MODULES_API_URL + '/cms/cms-spec-value/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,29 +0,0 @@
import type { PageParam } from '@/api';
/**
* 规格值
*/
export interface CmsSpecValue {
// 规格值ID
specValueId?: number;
// 规格组ID
specId?: number;
// 规格值
specValue?: string;
// 备注
comments?: string;
// 排序号
sortNumber?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 规格值搜索条件
*/
export interface CmsSpecValueParam extends PageParam {
specValueId?: number;
keywords?: string;
}

View File

@@ -1,106 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { MpOfficialMenu, MpOfficialMenuParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
/**
* 分页查询小程序端菜单
*/
export async function pageMpOfficialMenu(params: MpOfficialMenuParam) {
const res = await request.get<ApiResult<PageResult<MpOfficialMenu>>>(
MODULES_API_URL + '/cms/mp-official-menu/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询小程序端菜单列表
*/
export async function listMpOfficialMenu(params?: MpOfficialMenuParam) {
const res = await request.get<ApiResult<MpOfficialMenu[]>>(
MODULES_API_URL + '/cms/mp-official-menu',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加小程序端菜单
*/
export async function addMpOfficialMenu(data: MpOfficialMenu) {
const res = await request.post<ApiResult<unknown>>(
MODULES_API_URL + '/cms/mp-official-menu',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改小程序端菜单
*/
export async function updateMpOfficialMenu(data: MpOfficialMenu) {
const res = await request.put<ApiResult<unknown>>(
MODULES_API_URL + '/cms/mp-official-menu',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除小程序端菜单
*/
export async function removeMpOfficialMenu(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/mp-official-menu/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除小程序端菜单
*/
export async function removeBatchMpOfficialMenu(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
MODULES_API_URL + '/cms/mp-official-menu/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询小程序端菜单
*/
export async function getMpOfficialMenu(id: number) {
const res = await request.get<ApiResult<MpOfficialMenu>>(
MODULES_API_URL + '/cms/mp-official-menu/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,37 +0,0 @@
import type { PageParam } from '@/api';
/**
* 小程序端菜单
*/
export interface MpOfficialMenu {
// ID
id?: number;
// 上级id, 0是顶级
parentId?: number;
// 菜单名称
name?: string;
// 类型
type?: string;
// 菜单值
key?: string;
// 用户ID
userId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 小程序端菜单搜索条件
*/
export interface MpOfficialMenuParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -1,105 +0,0 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { ShopArticle, ShopArticleParam } from './model';
/**
* 分页查询商品文章
*/
export async function pageShopArticle(params: ShopArticleParam) {
const res = await request.get<ApiResult<PageResult<ShopArticle>>>(
'/shop/shop-article/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询商品文章列表
*/
export async function listShopArticle(params?: ShopArticleParam) {
const res = await request.get<ApiResult<ShopArticle[]>>(
'/shop/shop-article',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加商品文章
*/
export async function addShopArticle(data: ShopArticle) {
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-article',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改商品文章
*/
export async function updateShopArticle(data: ShopArticle) {
const res = await request.put<ApiResult<unknown>>(
'/shop/shop-article',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除商品文章
*/
export async function removeShopArticle(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
'/shop/shop-article/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除商品文章
*/
export async function removeBatchShopArticle(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
'/shop/shop-article/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询商品文章
*/
export async function getShopArticle(id: number) {
const res = await request.get<ApiResult<ShopArticle>>(
'/shop/shop-article/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -1,123 +0,0 @@
import type { PageParam } from '@/api';
/**
* 商品文章
*/
export interface ShopArticle {
// 文章ID
articleId?: number;
// 文章标题
title?: string;
// 文章类型 0常规 1视频
type?: number;
// 模型
model?: string;
// 详情页模板
detail?: string;
// 文章分类ID
categoryId?: number;
// 上级id, 0是顶级
parentId?: number;
// 话题
topic?: string;
// 标签
tags?: string;
// 封面图
image?: string;
// 封面图宽
imageWidth?: number;
// 封面图高
imageHeight?: number;
// 付费金额
price?: string;
// 开始时间
startTime?: string;
// 结束时间
endTime?: string;
// 来源
source?: string;
// 产品概述
overview?: string;
// 虚拟阅读量(仅用作展示)
virtualViews?: number;
// 实际阅读量
actualViews?: number;
// 评分
rate?: string;
// 列表显示方式(10小图展示 20大图展示)
showType?: number;
// 访问密码
password?: string;
// 可见类型 0所有人 1登录可见 2密码可见
permission?: number;
// 发布来源客户端 (APP、H5、小程序等)
platform?: string;
// 文章附件
files?: string;
// 视频地址
video?: string;
// 接受的文件类型
accept?: string;
// 经度
longitude?: string;
// 纬度
latitude?: string;
// 所在省份
province?: string;
// 所在城市
city?: string;
// 所在辖区
region?: string;
// 街道地址
address?: string;
// 点赞数
likes?: number;
// 评论数
commentNumbers?: number;
// 提醒谁看
toUsers?: string;
// 作者
author?: string;
// 推荐
recommend?: number;
// 报名人数
bmUsers?: number;
// 用户ID
userId?: number;
// 项目ID
projectId?: number;
// 语言
lang?: string;
// 关联默认语言的文章ID
langArticleId?: number;
// 是否自动翻译
translation?: string;
// 编辑器类型 0 Markdown编辑器 1 富文本编辑器
editor?: string;
// pdf文件地址
pdfUrl?: string;
// 版本号
version?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0已发布, 1待审核 2已驳回 3违规内容
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 商品文章搜索条件
*/
export interface ShopArticleParam extends PageParam {
articleId?: number;
keywords?: string;
}

View File

@@ -25,10 +25,7 @@ export async function listRoles(params?: RoleParam) {
const res = await request.get<ApiResult<Role[]>>( const res = await request.get<ApiResult<Role[]>>(
SERVER_API_URL + '/system/role', SERVER_API_URL + '/system/role',
{ {
params, params
headers: {
'TenantId': 10560
}
} }
); );
if (res.data.code === 0 && res.data.data) { if (res.data.code === 0 && res.data.data) {

View File

@@ -134,7 +134,6 @@ const startStatusCheck = () => {
qrCodeStatus.value = 'active'; qrCodeStatus.value = 'active';
stopAllTimers(); stopAllTimers();
emit('loginSuccess', status.accessToken || ''); emit('loginSuccess', status.accessToken || '');
message.success('登录成功');
break; break;
case 'expired': case 'expired':
qrCodeStatus.value = 'expired'; qrCodeStatus.value = 'expired';

View File

@@ -1,260 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑文档管理记录表' : '添加文档管理记录表'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="文档标题" name="title">
<a-input
allow-clear
placeholder="请输入文档标题"
v-model:value="form.title"
/>
</a-form-item>
<a-form-item label="上级目录" name="parentId">
<a-input
allow-clear
placeholder="请输入上级目录"
v-model:value="form.parentId"
/>
</a-form-item>
<a-form-item label="书籍ID" name="bookId">
<a-input
allow-clear
placeholder="请输入书籍ID"
v-model:value="form.bookId"
/>
</a-form-item>
<a-form-item label="可见性(public,private,protected)" name="visibility">
<a-input
allow-clear
placeholder="请输入可见性(public,private,protected)"
v-model:value="form.visibility"
/>
</a-form-item>
<a-form-item label="虚拟阅读量(仅用作展示)" name="virtualViews">
<a-input
allow-clear
placeholder="请输入虚拟阅读量(仅用作展示)"
v-model:value="form.virtualViews"
/>
</a-form-item>
<a-form-item label="实际阅读量" name="actualViews">
<a-input
allow-clear
placeholder="请输入实际阅读量"
v-model:value="form.actualViews"
/>
</a-form-item>
<a-form-item label="用户ID" name="userId">
<a-input
allow-clear
placeholder="请输入用户ID"
v-model:value="form.userId"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="排序(数字越小越靠前)" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="状态, 0正常, 1冻结" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">显示</a-radio>
<a-radio :value="1">隐藏</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="是否删除, 0否, 1是" name="deleted">
<a-input
allow-clear
placeholder="请输入是否删除, 0否, 1是"
v-model:value="form.deleted"
/>
</a-form-item>
<a-form-item label="修改时间" name="updateTime">
<a-input
allow-clear
placeholder="请输入修改时间"
v-model:value="form.updateTime"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsDocs, updateCmsDocs } from '@/api/cms/cmsDocs';
import { CmsDocs } from '@/api/cms/cmsDocs/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsDocs | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsDocs>({
docsId: undefined,
title: undefined,
parentId: undefined,
bookId: undefined,
visibility: undefined,
virtualViews: undefined,
actualViews: undefined,
userId: undefined,
comments: undefined,
sortNumber: undefined,
status: undefined,
deleted: undefined,
tenantId: undefined,
createTime: undefined,
updateTime: undefined,
cmsDocsId: undefined,
cmsDocsName: '',
status: 0,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsDocsName: [
{
required: true,
type: 'string',
message: '请填写文档管理记录表名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsDocs : addCmsDocs;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,287 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="cmsDocsId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsDocsEdit v-model:visible="showEdit" :data="current" @done="reload" />
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsDocsEdit from './components/cmsDocsEdit.vue';
import { pageCmsDocs, removeCmsDocs, removeBatchCmsDocs } from '@/api/cms/cmsDocs';
import type { CmsDocs, CmsDocsParam } from '@/api/cms/cmsDocs/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsDocs[]>([]);
// 当前编辑数据
const current = ref<CmsDocs | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsDocs({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '文档ID',
dataIndex: 'docsId',
key: 'docsId',
align: 'center',
width: 90,
},
{
title: '文档标题',
dataIndex: 'title',
key: 'title',
align: 'center',
},
{
title: '上级目录',
dataIndex: 'parentId',
key: 'parentId',
align: 'center',
},
{
title: '书籍ID',
dataIndex: 'bookId',
key: 'bookId',
align: 'center',
},
{
title: '可见性(public,private,protected)',
dataIndex: 'visibility',
key: 'visibility',
align: 'center',
},
{
title: '虚拟阅读量(仅用作展示)',
dataIndex: 'virtualViews',
key: 'virtualViews',
align: 'center',
},
{
title: '实际阅读量',
dataIndex: 'actualViews',
key: 'actualViews',
align: 'center',
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
align: 'center',
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center',
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
align: 'center',
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
align: 'center',
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
align: 'center',
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '修改时间',
dataIndex: 'updateTime',
key: 'updateTime',
align: 'center',
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsDocsParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsDocs) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsDocs) => {
const hide = message.loading('请求中..', 0);
removeCmsDocs(row.cmsDocsId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsDocs(selection.value.map((d) => d.cmsDocsId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsDocs) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsDocs'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,228 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑书籍记录表' : '添加书籍记录表'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="书籍名称" name="name">
<a-input
allow-clear
placeholder="请输入书籍名称"
v-model:value="form.name"
/>
</a-form-item>
<a-form-item label="书籍标识" name="code">
<a-input
allow-clear
placeholder="请输入书籍标识"
v-model:value="form.code"
/>
</a-form-item>
<a-form-item label="封面图" name="photo">
<a-input
allow-clear
placeholder="请输入封面图"
v-model:value="form.photo"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="文档内容" name="content">
<a-input
allow-clear
placeholder="请输入文档内容"
v-model:value="form.content"
/>
</a-form-item>
<a-form-item label="排序(数字越小越靠前)" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="状态, 0正常, 1冻结" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">显示</a-radio>
<a-radio :value="1">隐藏</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="是否删除, 0否, 1是" name="deleted">
<a-input
allow-clear
placeholder="请输入是否删除, 0否, 1是"
v-model:value="form.deleted"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsDocsBook, updateCmsDocsBook } from '@/api/cms/cmsDocsBook';
import { CmsDocsBook } from '@/api/cms/cmsDocsBook/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsDocsBook | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsDocsBook>({
bookId: undefined,
name: undefined,
code: undefined,
photo: undefined,
comments: undefined,
content: undefined,
sortNumber: undefined,
status: undefined,
deleted: undefined,
tenantId: undefined,
createTime: undefined,
cmsDocsBookId: undefined,
cmsDocsBookName: '',
status: 0,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsDocsBookName: [
{
required: true,
type: 'string',
message: '请填写书籍记录表名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsDocsBook : addCmsDocsBook;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,263 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="cmsDocsBookId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsDocsBookEdit v-model:visible="showEdit" :data="current" @done="reload" />
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsDocsBookEdit from './components/cmsDocsBookEdit.vue';
import { pageCmsDocsBook, removeCmsDocsBook, removeBatchCmsDocsBook } from '@/api/cms/cmsDocsBook';
import type { CmsDocsBook, CmsDocsBookParam } from '@/api/cms/cmsDocsBook/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsDocsBook[]>([]);
// 当前编辑数据
const current = ref<CmsDocsBook | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsDocsBook({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'bookId',
key: 'bookId',
align: 'center',
width: 90,
},
{
title: '书籍名称',
dataIndex: 'name',
key: 'name',
align: 'center',
},
{
title: '书籍标识',
dataIndex: 'code',
key: 'code',
align: 'center',
},
{
title: '封面图',
dataIndex: 'photo',
key: 'photo',
align: 'center',
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center',
},
{
title: '文档内容',
dataIndex: 'content',
key: 'content',
align: 'center',
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
align: 'center',
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
align: 'center',
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
align: 'center',
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsDocsBookParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsDocsBook) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsDocsBook) => {
const hide = message.loading('请求中..', 0);
removeCmsDocsBook(row.cmsDocsBookId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsDocsBook(selection.value.map((d) => d.cmsDocsBookId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsDocsBook) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsDocsBook'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,178 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑文档内容记录表' : '添加文档内容记录表'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="文档ID" name="docsId">
<a-input
allow-clear
placeholder="请输入文档ID"
v-model:value="form.docsId"
/>
</a-form-item>
<a-form-item label="文档内容" name="content">
<a-input
allow-clear
placeholder="请输入文档内容"
v-model:value="form.content"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsDocsContent, updateCmsDocsContent } from '@/api/cms/cmsDocsContent';
import { CmsDocsContent } from '@/api/cms/cmsDocsContent/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsDocsContent | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsDocsContent>({
id: undefined,
docsId: undefined,
content: undefined,
tenantId: undefined,
createTime: undefined,
cmsDocsContentId: undefined,
cmsDocsContentName: '',
status: 0,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsDocsContentName: [
{
required: true,
type: 'string',
message: '请填写文档内容记录表名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsDocsContent : addCmsDocsContent;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,227 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="cmsDocsContentId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsDocsContentEdit v-model:visible="showEdit" :data="current" @done="reload" />
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsDocsContentEdit from './components/cmsDocsContentEdit.vue';
import { pageCmsDocsContent, removeCmsDocsContent, removeBatchCmsDocsContent } from '@/api/cms/cmsDocsContent';
import type { CmsDocsContent, CmsDocsContentParam } from '@/api/cms/cmsDocsContent/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsDocsContent[]>([]);
// 当前编辑数据
const current = ref<CmsDocsContent | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsDocsContent({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
align: 'center',
width: 90,
},
{
title: '文档ID',
dataIndex: 'docsId',
key: 'docsId',
align: 'center',
},
{
title: '文档内容',
dataIndex: 'content',
key: 'content',
align: 'center',
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsDocsContentParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsDocsContent) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsDocsContent) => {
const hide = message.loading('请求中..', 0);
removeCmsDocsContent(row.cmsDocsContentId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsDocsContent(selection.value.map((d) => d.cmsDocsContentId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsDocsContent) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsDocsContent'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,284 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑小程序信息' : '添加小程序信息'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="头像" name="avatar">
<SelectFile
:placeholder="`请选择图片`"
:limit="1"
:data="images"
@done="chooseImage"
@del="onDeleteItem"
/>
</a-form-item>
<a-form-item label="小程序码" name="mpQrcode">
<SelectFile
:placeholder="`请选择图片`"
:limit="1"
:data="mpQrcode"
@done="chooseMpQrcode"
@del="onDeleteMpQrcode"
/>
</a-form-item>
<a-form-item label="小程序名称" name="mpName">
<a-input
allow-clear
placeholder="请输入小程序名称"
v-model:value="form.mpName"
/>
</a-form-item>
<a-form-item label="小程序ID" name="appId">
<a-input
allow-clear
placeholder="请输入小程序ID"
v-model:value="form.appId"
/>
</a-form-item>
<a-form-item label="小程序密钥" name="appSecret">
<a-input
allow-clear
placeholder="请输入小程序密钥"
type="password"
v-model:value="form.appSecret"
/>
</a-form-item>
<a-form-item label="主体信息" name="companyName">
<a-input
allow-clear
placeholder="请输入主体信息"
v-model:value="form.companyName"
/>
</a-form-item>
<a-form-item label="小程序备案" name="icpNo">
<a-input
allow-clear
placeholder="请输入小程序备案"
v-model:value="form.icpNo"
/>
</a-form-item>
<a-form-item label="登录邮箱" name="email">
<a-input
allow-clear
placeholder="请输入登录邮箱"
v-model:value="form.email"
/>
</a-form-item>
<a-form-item label="原始ID" name="ghId">
<a-input
allow-clear
placeholder="请输入原始ID"
v-model:value="form.ghId"
/>
</a-form-item>
<a-form-item label="排序" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="介绍" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="微信认证" name="authentication">
<a-radio-group v-model:value="form.authentication">
<a-radio :value="0">已认证</a-radio>
<a-radio :value="1">未认证</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsMp, updateCmsMp } from '@/api/cms/cmsMp';
import { CmsMp } from '@/api/cms/cmsMp/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsMp | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 表格选中数据
const mpQrcode = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsMp>({
mpId: undefined,
type: undefined,
appId: undefined,
appSecret: undefined,
mpName: undefined,
shortName: undefined,
avatar: undefined,
mpQrcode: undefined,
authentication: undefined,
companyName: undefined,
icpNo: undefined,
email: undefined,
password: undefined,
ghId: undefined,
mainPath: undefined,
expirationTime: undefined,
comments: undefined,
userId: undefined,
status: undefined,
deleted: undefined,
tenantId: undefined,
createTime: undefined,
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsMpName: [
{
required: true,
type: 'string',
message: '请填写小程序信息名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.avatar = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.avatar = '';
};
const chooseMpQrcode = (data: FileRecord) => {
mpQrcode.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.mpQrcode = data.downloadUrl;
};
const onDeleteMpQrcode = (index: number) => {
mpQrcode.value.splice(index, 1);
form.mpQrcode = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsMp : addCmsMp;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.avatar){
images.value.push({
uid: uuid(),
url: props.data.avatar,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,242 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="cmsMpId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'avatar'">
<a-image :src="record.avatar" :width="50" />
</template>
<template v-if="column.key === 'mpQrcode'">
<a-image :src="record.mpQrcode" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsMpEdit v-model:visible="showEdit" :data="current" @done="reload" />
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsMpEdit from './components/cmsMpEdit.vue';
import { pageCmsMp, removeCmsMp, removeBatchCmsMp } from '@/api/cms/cmsMp';
import type { CmsMp, CmsMpParam } from '@/api/cms/cmsMp/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsMp[]>([]);
// 当前编辑数据
const current = ref<CmsMp | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsMp({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '小程序名称',
dataIndex: 'mpName',
key: 'mpName',
align: 'center'
},
{
title: '头像',
dataIndex: 'avatar',
key: 'avatar',
align: 'center'
},
{
title: '小程序码',
dataIndex: 'mpQrcode',
key: 'mpQrcode',
align: 'center'
},
{
title: '主体信息',
dataIndex: 'companyName',
key: 'companyName',
align: 'center'
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
align: 'center',
hideInTable: true
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 120,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsMpParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsMp) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsMp) => {
const hide = message.loading('请求中..', 0);
removeCmsMp(row.cmsMpId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsMp(selection.value.map((d) => d.cmsMpId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsMp) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsMp'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,378 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑广告' : '添加广告'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="类型" name="adType">
<a-select
ref="select"
:disabled="isUpdate"
v-model:value="form.adType"
style="width: 120px"
>
<a-select-option value="图片广告">图片广告</a-select-option>
<a-select-option value="幻灯片">幻灯片</a-select-option>
<a-select-option value="视频广告">视频广告</a-select-option>
</a-select>
</a-form-item>
<template v-if="form.adType == '幻灯片'">
<a-form-item label="图片" name="images">
<SelectFile
:placeholder="`请选择图片`"
:limit="9"
:data="images"
@done="chooseFile"
@del="onDeleteItem"
/>
</a-form-item>
</template>
<template v-if="form.adType == '图片广告'">
<a-form-item label="图片" name="images">
<SelectFile
:limit="1"
:data="images"
@done="chooseFile"
@del="onDeleteItem"
/>
</a-form-item>
</template>
<template v-if="form.adType == '视频广告'">
<a-form-item
label="上传视频"
name="images"
extra="请上传视频文件仅支持mp4格式大小200M以内"
>
<SelectFile
:placeholder="`请选择视频文件`"
:limit="1"
:data="images"
@done="chooseFile"
@del="onDeleteItem"
/>
</a-form-item>
</template>
<a-form-item label="位置" name="pageId">
<SelectMpPages
:placeholder="`请选择页面`"
v-model:value="form.pageName"
@done="choosePageId"
/>
</a-form-item>
<a-form-item label="路由/链接地址" name="path">
<template v-if="form.adType == '幻灯片' && images.length > 0">
<template v-for="(item, index) in images" :key="index">
<a-input
allow-clear
:maxlength="100"
:placeholder="`请输入地址${index + 1}`"
v-model:value="pathList[index]"
/>
</template>
</template>
<template v-else>
<a-input
allow-clear
:maxlength="100"
placeholder="请输入路由/链接地址"
v-model:value="form.path"
/>
</template>
</a-form-item>
<a-form-item label="图标背景色" v-if="data && data.adId === 278">
<div class="flex justify-start items-start flex-wrap">
<div class="flex flex-col justify-center items-center" v-for="(item, index) in colors" :key="index">
<div
@click="changeShowColorPicker(index)"
class=" w-10 h-10 rounded-full m-2 cursor-pointer border-2 border-solid flex justify-center items-center text-red-600"
:class="[item ? 'border-none' : 'border-red-300']"
:style="{backgroundColor: item ?? 'red'}"
>{{ item ? '' : '选色' }}
</div>
<span v-if="item" class="text-sm cursor-pointer" @click="clearColor(index)">清除</span>
</div>
</div>
<!-- <Vue3ColorPicker v-if="showColorPicker" v-model="colors[showColorPickerIndex]" mode="solid"-->
<!-- :showColorList="false" :showEyeDrop="false" type="RGBA"/>-->
</a-form-item>
<a-form-item label="标题" name="name">
<a-input
allow-clear
:maxlength="100"
placeholder="请输入广告标题"
v-model:value="form.name"
/>
</a-form-item>
<a-form-item label="广告描述" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入广告描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="排序号" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="状态" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">开启</a-radio>
<a-radio :value="1">关闭</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import {ref, reactive, watch} from 'vue';
import {Form, message} from 'ant-design-vue';
import {assignObject} from 'ele-admin-pro';
import {addCmsMpAd, updateCmsMpAd} from '@/api/cms/cmsMpAd';
import {CmsMpAd} from '@/api/cms/cmsMpAd/model';
import {useThemeStore} from '@/store/modules/theme';
import {storeToRefs} from 'pinia';
import {FormInstance, type Rule, RuleObject} from 'ant-design-vue/es/form';
import {ItemType} from 'ele-admin-pro/es/ele-image-upload/types';
import {FileRecord} from '@/api/system/file/model';
import {CmsMpPages} from '@/api/cms/cmsMpPages/model';
// import {Vue3ColorPicker} from "@cyhnkckali/vue3-color-picker";
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const {styleResponsive} = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsMpAd | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 已上传数据
const images = ref<ItemType[]>([]);
const pathList = ref<any[]>([]);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
// 用户信息
const form = reactive<CmsMpAd>({
adId: undefined,
pageId: 0,
pageName: '',
name: '',
adType: '图片广告',
images: '',
colors: '',
width: '',
height: '',
path: '',
status: 0,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
adType: [
{
required: true,
type: 'string',
message: '请选择广告类型',
trigger: 'blur'
}
],
images: [
{
required: true,
type: 'string',
message: '请上传图片或视频',
trigger: 'blur',
validator: (_rule: Rule, value: string) => {
return new Promise<void>((resolve, reject) => {
if (images.value.length == 0) {
return reject('请上传图片或视频文件');
}
return resolve();
});
}
}
]
});
const {resetFields} = useForm(form, rules);
const chooseFile = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.downloadUrl,
status: 'done'
});
form.images = data.downloadUrl;
colors.value.push('')
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
colors.value.splice(index, 1);
form.images = '';
};
const choosePageId = (data: CmsMpPages) => {
form.pageName = data.title;
form.pageId = data.id;
};
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form,
images: JSON.stringify(images.value),
colors: JSON.stringify(colors.value),
path:
form.adType == '幻灯片' ? JSON.stringify(pathList.value) : form.path
};
const saveOrUpdate = isUpdate.value ? updateCmsMpAd : addCmsMpAd;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {
});
};
const colors = ref<string[]>([])
const showColorPicker = ref(false)
const showColorPickerIndex = ref<number>(-1)
const changeShowColorPicker = (index: number) => {
if (showColorPickerIndex.value === index) showColorPicker.value = !showColorPicker.value
else {
showColorPickerIndex.value = index
showColorPicker.value = true
}
}
const clearColor = (index) => {
showColorPicker.value = false
colors.value[index] = ''
}
watch(
() => props.visible,
(visible) => {
if (visible) {
if (props.data) {
assignObject(form, props.data);
images.value = [];
pathList.value = [];
colors.value = []
if (props.data.images) {
const arr = JSON.parse(props.data.images);
arr.map((d) => {
images.value.push({
uid: d.uid,
url: d.url,
status: 'done'
});
});
}
if (props.data.colors) {
colors.value = JSON.parse(props.data.colors);
} else {
colors.value = []
for (let i = 0; i < images.value.length; i++) {
colors.value.push('')
}
}
if (props.data.adType == '幻灯片') {
const arr = JSON.parse(props.data.path);
arr.map((d) => {
pathList.value.push(d);
});
}
isUpdate.value = true;
} else {
images.value = [];
isUpdate.value = false;
}
} else {
resetFields();
}
},
{immediate: true}
);
</script>
<style lang="less">
.tab-pane {
min-height: 300px;
}
.ml-10 {
margin-left: 5px;
}
.upload-text {
margin-right: 70px;
}
.icon-bg {
width: 50px;
height: 50px;
display: block;
border-radius: 50px;
background: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(6.123233995736766e-17%2C%201%2C%20-0.024693877551020406%2C%206.123233995736766e-17%2C%200.5%2C%200)%22%3E%3Cstop%20stop-color%3D%22%230a060d%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23660061%22%20stop-opacity%3D%221%22%20offset%3D%220.95%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E');
}
</style>

View File

@@ -1,60 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
<a-input-search
allow-clear
placeholder="请输入关键词"
v-model:value="where.keywords"
@pressEnter="search"
@search="search"
/>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import { watch } from 'vue';
import useSearch from '@/utils/use-search';
import { CmsMpAdParam } from '@/api/cms/cmsMpAd/model';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: CmsMpAdParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
// 表单数据
const { where, resetFields } = useSearch<CmsMpAdParam>({
adId: undefined,
keywords: undefined
});
const search = () => {
emit('search', where);
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,250 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="adId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'adType'">
<a-tag>{{ record.adType }}</a-tag>
</template>
<template v-if="column.key === 'images'">
<template
v-for="(item, index) in JSON.parse(record.images)"
:key="index"
>
<a-image :src="item.url" :width="80" />
</template>
<span></span>
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">开启</a-tag>
<a-tag v-if="record.status === 1" color="red">关闭</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm v-if="record.adId !== 278"
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<MpAdEdit v-model:visible="showEdit" :data="current" @done="reload" />
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import MpAdEdit from './components/mpAdEdit.vue';
import { pageCmsMpAd, removeCmsMpAd, removeBatchCmsMpAd } from '@/api/cms/cmsMpAd';
import type { CmsMpAd, CmsMpAdParam } from '@/api/cms/cmsMpAd/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsMpAd[]>([]);
// 当前编辑数据
const current = ref<CmsMpAd | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsMpAd({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: 'ID',
width: 90,
dataIndex: 'adId'
},
{
title: '类型',
dataIndex: 'adType',
key: 'adType',
width: 120
},
{
title: '广告图片',
dataIndex: 'images',
key: 'images'
},
{
title: '跳转路径',
dataIndex: 'path',
key: 'path',
width: 280,
ellipsis: true
},
// {
// title: '位置',
// dataIndex: 'pageName',
// key: 'pageName',
// width: 120
// },
{
title: '描述',
dataIndex: 'comments',
key: 'path',
width: 280,
ellipsis: true
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
align: 'center',
width: 120
},
{
title: '操作',
key: 'action',
width: 120,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsMpAdParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsMpAd) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsMpAd) => {
const hide = message.loading('请求中..', 0);
removeCmsMpAd(row.adId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsMpAd(selection.value.map((d) => d.adId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsMpAd) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'MpAd'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,216 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑小程序配置' : '添加小程序配置'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="类型0文本 1图片 2其他" name="type">
<a-input
allow-clear
placeholder="请输入类型0文本 1图片 2其他"
v-model:value="form.type"
/>
</a-form-item>
<a-form-item label="名称" name="name">
<a-input
allow-clear
placeholder="请输入名称"
v-model:value="form.name"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="名称" name="value">
<a-input
allow-clear
placeholder="请输入名称"
v-model:value="form.value"
/>
</a-form-item>
<a-form-item label="页面ID" name="pageId">
<a-input
allow-clear
placeholder="请输入页面ID"
v-model:value="form.pageId"
/>
</a-form-item>
<a-form-item label="排序(数字越小越靠前)" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="是否删除, 0否, 1是" name="deleted">
<a-input
allow-clear
placeholder="请输入是否删除, 0否, 1是"
v-model:value="form.deleted"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsMpField, updateCmsMpField } from '@/api/cms/cmsMpField';
import { CmsMpField } from '@/api/cms/cmsMpField/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsMpField | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsMpField>({
id: undefined,
type: undefined,
name: undefined,
comments: undefined,
value: undefined,
pageId: undefined,
deleted: undefined,
tenantId: undefined,
createTime: undefined,
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsMpFieldName: [
{
required: true,
type: 'string',
message: '请填写小程序配置名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsMpField : addCmsMpField;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,256 +0,0 @@
<template>
<a-page-header :title="getPageTitle()" @back="() => $router.go(-1)">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="cmsMpFieldId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50"/>
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical"/>
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsMpFieldEdit v-model:visible="showEdit" :data="current" @done="reload"/>
</a-page-header>
</template>
<script lang="ts" setup>
import {createVNode, ref} from 'vue';
import {message, Modal} from 'ant-design-vue';
import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
import type {EleProTable} from 'ele-admin-pro';
import {toDateString} from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsMpFieldEdit from './components/cmsMpFieldEdit.vue';
import {pageCmsMpField, removeCmsMpField, removeBatchCmsMpField} from '@/api/cms/cmsMpField';
import type {CmsMpField, CmsMpFieldParam} from '@/api/cms/cmsMpField/model';
import {getPageTitle} from "@/utils/common";
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsMpField[]>([]);
// 当前编辑数据
const current = ref<CmsMpField | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsMpField({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '自增ID',
dataIndex: 'id',
key: 'id',
align: 'center',
width: 90,
},
{
title: '类型0文本 1图片 2其他',
dataIndex: 'type',
key: 'type',
align: 'center',
},
{
title: '名称',
dataIndex: 'name',
key: 'name',
align: 'center',
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center',
},
{
title: '名称',
dataIndex: 'value',
key: 'value',
align: 'center',
},
{
title: '页面ID',
dataIndex: 'pageId',
key: 'pageId',
align: 'center',
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
align: 'center',
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
align: 'center',
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({text}) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsMpFieldParam) => {
selection.value = [];
tableRef?.value?.reload({where: where});
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsMpField) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsMpField) => {
const hide = message.loading('请求中..', 0);
removeCmsMpField(row.cmsMpFieldId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsMpField(selection.value.map((d) => d.cmsMpFieldId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsMpField) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsMpField'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,178 +0,0 @@
<!-- 分组编辑弹窗 -->
<template>
<ele-modal
:width="460"
:visible="visible"
:confirm-loading="loading"
:title="isUpdate ? '修改分组' : '添加分组'"
:body-style="{ paddingBottom: '8px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 5, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="分组标识" name="dictCode">
<a-input
allow-clear
:maxlength="20"
disabled
placeholder="请输入分组标识"
v-model:value="form.dictCode"
/>
</a-form-item>
<a-form-item label="分组名称" name="dictDataName">
<a-input
allow-clear
:maxlength="20"
placeholder="请输入分组名称"
v-model:value="form.dictDataName"
/>
</a-form-item>
<a-form-item label="排序" name="sortNumber">
<a-input-number
:min="0"
:max="99999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="备注">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入备注"
v-model:value="form.comments"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { message } from 'ant-design-vue/es';
import type { FormInstance, Rule } from 'ant-design-vue/es/form';
import { storeToRefs } from 'pinia';
import { useThemeStore } from '@/store/modules/theme';
import useFormData from '@/utils/use-form-data';
import { addDictData, updateDictData } from '@/api/system/dict-data';
import { DictData } from '@/api/system/dict-data/model';
import {removeSiteInfoCache} from "@/api/cms/cmsWebsite";
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: DictData | null;
// 字典ID
dictId?: number | 0;
}>();
//
const formRef = ref<FormInstance | null>(null);
// 是否是修改
const isUpdate = ref(false);
// 提交状态
const loading = ref(false);
// 表单数据
const { form, resetFields, assignFields } = useFormData<DictData>({
dictId: undefined,
dictDataId: undefined,
dictDataName: '',
dictCode: 'mpGroup',
dictDataCode: '',
sortNumber: 100,
comments: ''
});
// 表单验证规则
const rules = reactive<Record<string, Rule[]>>({
dictDataCode: [
{
required: true,
message: '请输入分组名称',
type: 'string',
trigger: 'blur'
}
],
dictCode: [
{
required: true,
message: '请输入分组标识',
type: 'string',
trigger: 'blur'
}
]
});
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const saveOrUpdate = isUpdate.value ? updateDictData : addDictData;
form.dictDataCode = form.dictDataName;
form.dictId = props.dictId;
saveOrUpdate(form)
.then((msg) => {
loading.value = false;
message.success(msg);
// 清除字典缓存
removeSiteInfoCache(form.dictCode + ':' + form.tenantId);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
watch(
() => props.visible,
(visible) => {
if (visible) {
if (props.data) {
assignFields(props.data);
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
formRef.value?.clearValidate();
}
}
);
</script>

View File

@@ -1,228 +0,0 @@
<template>
<div class="ele-body">
<a-card :bordered="false">
<!-- 表格 -->
<ele-pro-table
ref="tableRef"
row-key="dictDataId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
:scroll="{ x: 800 }"
cache-key="appDictTable"
>
<template #toolbar>
<a-space>
<a-button type="primary" class="ele-btn-icon" @click="openEdit()">
<template #icon>
<plus-outlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
placement="topRight"
title="确定要删除此分组吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<dict-edit
v-model:visible="showEdit"
:dictId="dictId"
:data="current"
@done="reload"
/>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref, watch } from 'vue';
import { message, Modal } from 'ant-design-vue/es';
import {
PlusOutlined,
ExclamationCircleOutlined
} from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro/es';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import { messageLoading } from 'ele-admin-pro/es';
import DictEdit from './components/dict-edit.vue';
import {
pageDictData,
removeDictData,
removeDictDataBatch
} from '@/api/system/dict-data';
import { DictParam } from '@/api/system/dict/model';
import { DictData } from '@/api/system/dict-data/model';
import { addDict, listDictionaries } from '@/api/system/dict';
import { Dictionary } from '@/api/system/dictionary/model';
import router from '@/router';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
const dictId = ref(0);
const pageId = ref(0);
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'dictDataId',
width: 80,
hideInTable: true
},
{
title: '分组名称',
dataIndex: 'dictDataName',
showSorterTooltip: false
},
{
title: '备注',
dataIndex: 'comments',
sorter: true,
showSorterTooltip: false
},
{
title: '排序号',
width: 180,
align: 'center',
dataIndex: 'sortNumber'
},
{
title: '操作',
key: 'action',
width: 180,
align: 'center'
}
]);
// 表格选中数据
const selection = ref<DictData[]>([]);
// 当前编辑数据
const current = ref<Dictionary | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 表格数据源
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
where.dictCode = 'mpGroup';
return pageDictData({ ...where, ...orders, page, limit });
};
/* 搜索 */
const reload = (where?: DictParam) => {
selection.value = [];
tableRef?.value?.reload({ page: 1, where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: DictData) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 删除单个 */
const remove = (row: DictData) => {
const hide = messageLoading('请求中..', 0);
removeDictData(row.dictDataId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的分组吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = messageLoading('请求中..', 0);
removeDictDataBatch(selection.value.map((d) => d.dictDataId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
// 初始化字典
const loadDict = () => {
listDictionaries({ dictCode: 'mpGroup' }).then(async (data) => {
if (data?.length == 0) {
await addDict({ dictCode: 'mpGroup', dictName: '链接分组' });
}
await listDictionaries({ dictCode: 'mpGroup' }).then((list) => {
list?.map((d) => {
dictId.value = Number(d.dictId);
});
});
});
};
loadDict();
/* 自定义行属性 */
const customRow = (record: DictData) => {
return {
onDblclick: () => {
openEdit(record);
}
};
};
watch(
() => router.currentRoute.value.params.id,
(id) => {
if (id) {
if (id == ':id') {
pageId.value = 0;
} else {
pageId.value = Number(id);
}
}
reload();
},
{ immediate: true }
);
</script>
<script lang="ts">
export default {
name: 'TaskDictData'
};
</script>

View File

@@ -1,391 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑小程序端菜单' : '添加小程序端菜单'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="上级id, 0是顶级" name="parentId">
<a-input
allow-clear
placeholder="请输入上级id, 0是顶级"
v-model:value="form.parentId"
/>
</a-form-item>
<a-form-item label="菜单名称" name="title">
<a-input
allow-clear
placeholder="请输入菜单名称"
v-model:value="form.title"
/>
</a-form-item>
<a-form-item label="类型 0功能图标 1订单状态图标 2首页导航图标 3 商城导航图标 4管理人员功能图标" name="type">
<a-input
allow-clear
placeholder="请输入类型 0功能图标 1订单状态图标 2首页导航图标 3 商城导航图标 4管理人员功能图标"
v-model:value="form.type"
/>
</a-form-item>
<a-form-item label="是否微信小程序菜单" name="isMpWeixin">
<a-input
allow-clear
placeholder="请输入是否微信小程序菜单"
v-model:value="form.isMpWeixin"
/>
</a-form-item>
<a-form-item label="菜单路由地址" name="path">
<a-input
allow-clear
placeholder="请输入菜单路由地址"
v-model:value="form.path"
/>
</a-form-item>
<a-form-item label="菜单组件地址, 目录可为空" name="component">
<a-input
allow-clear
placeholder="请输入菜单组件地址, 目录可为空"
v-model:value="form.component"
/>
</a-form-item>
<a-form-item label="打开位置" name="target">
<a-input
allow-clear
placeholder="请输入打开位置"
v-model:value="form.target"
/>
</a-form-item>
<a-form-item label="菜单图标" name="avatar">
<a-input
allow-clear
placeholder="请输入菜单图标"
v-model:value="form.avatar"
/>
</a-form-item>
<a-form-item label="图标颜色" name="color">
<a-input
allow-clear
placeholder="请输入图标颜色"
v-model:value="form.color"
/>
</a-form-item>
<a-form-item label="上传图标" name="icon">
<a-input
allow-clear
placeholder="请输入上传图标"
v-model:value="form.icon"
/>
</a-form-item>
<a-form-item label="是否隐藏, 0否, 1是(仅注册路由不显示在左侧菜单)" name="hide">
<a-input
allow-clear
placeholder="请输入是否隐藏, 0否, 1是(仅注册路由不显示在左侧菜单)"
v-model:value="form.hide"
/>
</a-form-item>
<a-form-item label="位置 0不限 1顶部 2底部" name="position">
<a-input
allow-clear
placeholder="请输入位置 0不限 1顶部 2底部"
v-model:value="form.position"
/>
</a-form-item>
<a-form-item label="0 第一行 1第二行" name="rows">
<a-input
allow-clear
placeholder="请输入0 第一行 1第二行"
v-model:value="form.rows"
/>
</a-form-item>
<a-form-item label="菜单侧栏选中的path" name="active">
<a-input
allow-clear
placeholder="请输入菜单侧栏选中的path"
v-model:value="form.active"
/>
</a-form-item>
<a-form-item label="其它路由元信息" name="meta">
<a-input
allow-clear
placeholder="请输入其它路由元信息"
v-model:value="form.meta"
/>
</a-form-item>
<a-form-item label="绑定的页面" name="pageId">
<a-input
allow-clear
placeholder="请输入绑定的页面"
v-model:value="form.pageId"
/>
</a-form-item>
<a-form-item label="绑定的文章分类ID" name="articleCategoryId">
<a-input
allow-clear
placeholder="请输入绑定的文章分类ID"
v-model:value="form.articleCategoryId"
/>
</a-form-item>
<a-form-item label="绑定的文章ID" name="articleId">
<a-input
allow-clear
placeholder="请输入绑定的文章ID"
v-model:value="form.articleId"
/>
</a-form-item>
<a-form-item label="绑定的表单ID" name="formId">
<a-input
allow-clear
placeholder="请输入绑定的表单ID"
v-model:value="form.formId"
/>
</a-form-item>
<a-form-item label="绑定的书籍标识" name="bookCode">
<a-input
allow-clear
placeholder="请输入绑定的书籍标识"
v-model:value="form.bookCode"
/>
</a-form-item>
<a-form-item label="绑定的商品分类ID" name="goodsCategoryId">
<a-input
allow-clear
placeholder="请输入绑定的商品分类ID"
v-model:value="form.goodsCategoryId"
/>
</a-form-item>
<a-form-item label="绑定的商品ID" name="goodsId">
<a-input
allow-clear
placeholder="请输入绑定的商品ID"
v-model:value="form.goodsId"
/>
</a-form-item>
<a-form-item label="用户ID" name="userId">
<a-input
allow-clear
placeholder="请输入用户ID"
v-model:value="form.userId"
/>
</a-form-item>
<a-form-item label="是否管理人员可见" name="adminShow">
<a-input
allow-clear
placeholder="请输入是否管理人员可见"
v-model:value="form.adminShow"
/>
</a-form-item>
<a-form-item label="设为首页" name="home">
<a-input
allow-clear
placeholder="请输入设为首页"
v-model:value="form.home"
/>
</a-form-item>
<a-form-item label="分组名称" name="groupName">
<a-input
allow-clear
placeholder="请输入分组名称"
v-model:value="form.groupName"
/>
</a-form-item>
<a-form-item label="排序(数字越小越靠前)" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="状态, 0正常, 1冻结" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">显示</a-radio>
<a-radio :value="1">隐藏</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsMpMenu, updateCmsMpMenu } from '@/api/cms/cmsMpMenu';
import { CmsMpMenu } from '@/api/cms/cmsMpMenu/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsMpMenu | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsMpMenu>({
menuId: undefined,
parentId: undefined,
title: undefined,
type: undefined,
isMpWeixin: undefined,
path: undefined,
component: undefined,
target: undefined,
avatar: undefined,
color: undefined,
icon: undefined,
hide: undefined,
position: undefined,
rows: undefined,
active: undefined,
meta: undefined,
pageId: undefined,
articleCategoryId: undefined,
articleId: undefined,
formId: undefined,
bookCode: undefined,
goodsCategoryId: undefined,
goodsId: undefined,
userId: undefined,
adminShow: undefined,
home: undefined,
groupName: undefined,
comments: undefined,
status: undefined,
tenantId: undefined,
createTime: undefined,
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsMpMenuName: [
{
required: true,
type: 'string',
message: '请填写小程序端菜单名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsMpMenu : addCmsMpMenu;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,389 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="cmsMpMenuId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsMpMenuEdit v-model:visible="showEdit" :data="current" @done="reload" />
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsMpMenuEdit from './components/cmsMpMenuEdit.vue';
import { pageCmsMpMenu, removeCmsMpMenu, removeBatchCmsMpMenu } from '@/api/cms/cmsMpMenu';
import type { CmsMpMenu, CmsMpMenuParam } from '@/api/cms/cmsMpMenu/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsMpMenu[]>([]);
// 当前编辑数据
const current = ref<CmsMpMenu | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsMpMenu({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'menuId',
key: 'menuId',
align: 'center',
width: 90,
},
{
title: '上级id, 0是顶级',
dataIndex: 'parentId',
key: 'parentId',
align: 'center',
},
{
title: '菜单名称',
dataIndex: 'title',
key: 'title',
align: 'center',
},
{
title: '类型 0功能图标 1订单状态图标 2首页导航图标 3 商城导航图标 4管理人员功能图标',
dataIndex: 'type',
key: 'type',
align: 'center',
},
{
title: '是否微信小程序菜单',
dataIndex: 'isMpWeixin',
key: 'isMpWeixin',
align: 'center',
},
{
title: '菜单路由地址',
dataIndex: 'path',
key: 'path',
align: 'center',
},
{
title: '菜单组件地址, 目录可为空',
dataIndex: 'component',
key: 'component',
align: 'center',
},
{
title: '打开位置',
dataIndex: 'target',
key: 'target',
align: 'center',
},
{
title: '菜单图标',
dataIndex: 'avatar',
key: 'avatar',
align: 'center',
},
{
title: '图标颜色',
dataIndex: 'color',
key: 'color',
align: 'center',
},
{
title: '上传图标',
dataIndex: 'icon',
key: 'icon',
align: 'center',
},
{
title: '是否隐藏, 0否, 1是(仅注册路由不显示在左侧菜单)',
dataIndex: 'hide',
key: 'hide',
align: 'center',
},
{
title: '位置 0不限 1顶部 2底部',
dataIndex: 'position',
key: 'position',
align: 'center',
},
{
title: '0 第一行 1第二行',
dataIndex: 'rows',
key: 'rows',
align: 'center',
},
{
title: '菜单侧栏选中的path',
dataIndex: 'active',
key: 'active',
align: 'center',
},
{
title: '其它路由元信息',
dataIndex: 'meta',
key: 'meta',
align: 'center',
},
{
title: '绑定的页面',
dataIndex: 'pageId',
key: 'pageId',
align: 'center',
},
{
title: '绑定的文章分类ID',
dataIndex: 'articleCategoryId',
key: 'articleCategoryId',
align: 'center',
},
{
title: '绑定的文章ID',
dataIndex: 'articleId',
key: 'articleId',
align: 'center',
},
{
title: '绑定的表单ID',
dataIndex: 'formId',
key: 'formId',
align: 'center',
},
{
title: '绑定的书籍标识',
dataIndex: 'bookCode',
key: 'bookCode',
align: 'center',
},
{
title: '绑定的商品分类ID',
dataIndex: 'goodsCategoryId',
key: 'goodsCategoryId',
align: 'center',
},
{
title: '绑定的商品ID',
dataIndex: 'goodsId',
key: 'goodsId',
align: 'center',
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
align: 'center',
},
{
title: '是否管理人员可见',
dataIndex: 'adminShow',
key: 'adminShow',
align: 'center',
},
{
title: '设为首页',
dataIndex: 'home',
key: 'home',
align: 'center',
},
{
title: '分组名称',
dataIndex: 'groupName',
key: 'groupName',
align: 'center',
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
align: 'center',
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center',
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
align: 'center',
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsMpMenuParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsMpMenu) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsMpMenu) => {
const hide = message.loading('请求中..', 0);
removeCmsMpMenu(row.cmsMpMenuId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsMpMenu(selection.value.map((d) => d.cmsMpMenuId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsMpMenu) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsMpMenu'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,220 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑微信公众号' : '添加微信公众号'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="上级id, 0是顶级" name="parentId">
<a-input
allow-clear
placeholder="请输入上级id, 0是顶级"
v-model:value="form.parentId"
/>
</a-form-item>
<a-form-item label="菜单名称" name="name">
<a-input
allow-clear
placeholder="请输入菜单名称"
v-model:value="form.name"
/>
</a-form-item>
<a-form-item label="类型" name="type">
<a-input
allow-clear
placeholder="请输入类型"
v-model:value="form.type"
/>
</a-form-item>
<a-form-item label="菜单值" name="key">
<a-input
allow-clear
placeholder="请输入菜单值"
v-model:value="form.key"
/>
</a-form-item>
<a-form-item label="排序(数字越小越靠前)" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="状态, 0正常, 1冻结" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">显示</a-radio>
<a-radio :value="1">隐藏</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsMpOfficialMenu, updateCmsMpOfficialMenu } from '@/api/cms/cmsMpOfficialMenu';
import { CmsMpOfficialMenu } from '@/api/cms/cmsMpOfficialMenu/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsMpOfficialMenu | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsMpOfficialMenu>({
id: undefined,
parentId: undefined,
name: undefined,
type: undefined,
key: undefined,
sortNumber: undefined,
comments: undefined,
status: undefined,
tenantId: undefined,
createTime: undefined,
cmsMpOfficialMenuId: undefined,
cmsMpOfficialMenuName: '',
status: 0,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsMpOfficialMenuName: [
{
required: true,
type: 'string',
message: '请填写微信公众号名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsMpOfficialMenu : addCmsMpOfficialMenu;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,257 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="cmsMpOfficialMenuId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsMpOfficialMenuEdit v-model:visible="showEdit" :data="current" @done="reload" />
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsMpOfficialMenuEdit from './components/cmsMpOfficialMenuEdit.vue';
import { pageCmsMpOfficialMenu, removeCmsMpOfficialMenu, removeBatchCmsMpOfficialMenu } from '@/api/cms/cmsMpOfficialMenu';
import type { CmsMpOfficialMenu, CmsMpOfficialMenuParam } from '@/api/cms/cmsMpOfficialMenu/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsMpOfficialMenu[]>([]);
// 当前编辑数据
const current = ref<CmsMpOfficialMenu | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsMpOfficialMenu({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
align: 'center',
width: 90,
},
{
title: '上级id, 0是顶级',
dataIndex: 'parentId',
key: 'parentId',
align: 'center',
},
{
title: '菜单名称',
dataIndex: 'name',
key: 'name',
align: 'center',
},
{
title: '类型',
dataIndex: 'type',
key: 'type',
align: 'center',
},
{
title: '菜单值',
dataIndex: 'key',
key: 'key',
align: 'center',
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
align: 'center',
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center',
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
align: 'center',
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsMpOfficialMenuParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsMpOfficialMenu) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsMpOfficialMenu) => {
const hide = message.loading('请求中..', 0);
removeCmsMpOfficialMenu(row.cmsMpOfficialMenuId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsMpOfficialMenu(selection.value.map((d) => d.cmsMpOfficialMenuId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsMpOfficialMenu) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsMpOfficialMenu'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,195 +0,0 @@
<!-- 分包编辑弹窗 -->
<template>
<ele-modal
:width="460"
:visible="visible"
:confirm-loading="loading"
:title="isUpdate ? '修改分包' : '添加分包'"
:body-style="{ paddingBottom: '8px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 5, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="标识" name="dictCode">
<a-input
allow-clear
:maxlength="20"
disabled
placeholder="请输入标识"
v-model:value="form.dictCode"
/>
</a-form-item>
<!-- <a-form-item label="名称" name="dictDataName">-->
<!-- <a-input-->
<!-- allow-clear-->
<!-- :maxlength="20"-->
<!-- placeholder="分包"-->
<!-- v-model:value="form.dictDataName"-->
<!-- />-->
<!-- </a-form-item>-->
<a-form-item label="名称" name="dictDataCode">
<a-input
allow-clear
:maxlength="20"
placeholder="pages"
v-model:value="form.dictDataCode"
/>
</a-form-item>
<a-form-item label="排序" name="sortNumber">
<a-input-number
:min="0"
:max="99999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="备注">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入备注"
v-model:value="form.comments"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { message } from 'ant-design-vue/es';
import type { FormInstance, Rule } from 'ant-design-vue/es/form';
import { storeToRefs } from 'pinia';
import { useThemeStore } from '@/store/modules/theme';
import useFormData from '@/utils/use-form-data';
import { addDictData, updateDictData } from '@/api/system/dict-data';
import { DictData } from '@/api/system/dict-data/model';
import {removeSiteInfoCache} from "@/api/cms/cmsWebsite";
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: DictData | null;
// 字典ID
dictId?: number | 0;
}>();
//
const formRef = ref<FormInstance | null>(null);
// 是否是修改
const isUpdate = ref(false);
// 提交状态
const loading = ref(false);
// 表单数据
const { form, resetFields, assignFields } = useFormData<DictData>({
dictId: undefined,
dictDataId: undefined,
dictDataName: '',
dictCode: 'mpPackage',
dictDataCode: '',
sortNumber: 100,
comments: ''
});
// 表单验证规则
const rules = reactive<Record<string, Rule[]>>({
dictDataCode: [
{
required: true,
message: '请输入分包英文名',
type: 'string',
trigger: 'blur'
}
],
// dictDataName: [
// {
// required: true,
// message: '请输入分包名称',
// type: 'string',
// trigger: 'blur'
// }
// ],
dictCode: [
{
required: true,
message: '请输入分包标识',
type: 'string',
trigger: 'blur'
}
]
});
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const saveOrUpdate = isUpdate.value ? updateDictData : addDictData;
// form.dictDataCode = form.dictDataName;
form.dictId = props.dictId;
form.dictDataName = form.dictDataCode;
saveOrUpdate(form)
.then((msg) => {
loading.value = false;
message.success(msg);
// 清除字典缓存
removeSiteInfoCache(form.dictCode + ':' + form.tenantId);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
watch(
() => props.visible,
(visible) => {
if (visible) {
if (props.data) {
assignFields(props.data);
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
formRef.value?.clearValidate();
}
}
);
</script>

View File

@@ -1,223 +0,0 @@
<template>
<a-page-header :title="getPageTitle()" @back="() => $router.go(-1)">
<template #extra>
<Extra/>
</template>
<a-card :bordered="false">
<!-- 表格 -->
<ele-pro-table
ref="tableRef"
row-key="dictDataId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
:scroll="{ x: 800 }"
cache-key="appDictTable"
>
<template #toolbar>
<a-space>
<a-button type="primary" class="ele-btn-icon" @click="openEdit()">
<template #icon>
<plus-outlined/>
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<a-space v-if="record.dictDataName !== 'MainPackage'">
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical"/>
<a-popconfirm
placement="topRight"
title="确定要删除此分包吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<dict-edit
v-model:visible="showEdit"
:dictId="dictId"
:data="current"
@done="reload"
/>
</a-page-header>
</template>
<script lang="ts" setup>
import {createVNode, ref} from 'vue';
import {message, Modal} from 'ant-design-vue/es';
import {
PlusOutlined,
DeleteOutlined,
ExclamationCircleOutlined
} from '@ant-design/icons-vue';
import type {EleProTable} from 'ele-admin-pro/es';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import {messageLoading} from 'ele-admin-pro/es';
import DictEdit from './components/dict-edit.vue';
import {
pageDictData,
removeDictData,
removeDictDataBatch
} from '@/api/system/dict-data';
import {DictParam} from '@/api/system/dict/model';
import {DictData} from '@/api/system/dict-data/model';
import {addDict, listDictionaries} from '@/api/system/dict';
import {Dictionary} from '@/api/system/dictionary/model';
import {getPageTitle} from "@/utils/common";
import Extra from "@/views/cms/cmsNavigation/components/extra.vue";
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
const dictId = ref(0);
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'dictDataId',
width: 80,
hideInTable: true
},
{
title: '分包',
dataIndex: 'dictDataCode',
showSorterTooltip: false
},
// {
// title: '英文名',
// dataIndex: 'dictDataCode',
// showSorterTooltip: false
// },
{
title: '备注',
dataIndex: 'comments',
showSorterTooltip: false
},
{
title: '排序号',
width: 180,
align: 'center',
dataIndex: 'sortNumber'
},
{
title: '操作',
key: 'action',
width: 180,
align: 'center'
}
]);
// 表格选中数据
const selection = ref<DictData[]>([]);
// 当前编辑数据
const current = ref<Dictionary | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 表格数据源
const datasource: DatasourceFunction = ({page, limit, where, orders}) => {
where.dictCode = 'mpPackage';
return pageDictData({...where, ...orders, page, limit});
};
/* 搜索 */
const reload = (where?: DictParam) => {
selection.value = [];
tableRef?.value?.reload({page: 1, where});
};
/* 打开编辑弹窗 */
const openEdit = (row?: DictData) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 删除单个 */
const remove = (row: DictData) => {
const hide = messageLoading('请求中..', 0);
removeDictData(row.dictDataId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的分包吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = messageLoading('请求中..', 0);
removeDictDataBatch(selection.value.map((d) => d.dictDataId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
// 初始化字典
const loadDict = () => {
listDictionaries({dictCode: 'mpPackage'}).then(async (data) => {
if (data?.length == 0) {
await addDict({dictCode: 'mpPackage', dictName: '链接分包'});
}
await listDictionaries({dictCode: 'mpPackage'}).then((list) => {
list?.map((d) => {
dictId.value = Number(d.dictId);
});
});
});
};
loadDict();
/* 自定义行属性 */
const customRow = (record: DictData) => {
return {
onDblclick: () => {
if (record.dictDataName === 'package') {
openEdit(record);
}
}
};
};
</script>
<script lang="ts">
export default {
name: 'TaskDictData'
};
</script>

View File

@@ -1,281 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑页面' : '添加页面'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="上级分类" name="parentId">
<a-tree-select
allow-clear
:tree-data="pages"
tree-default-expand-all
placeholder="请选择上级分类"
:value="form.parentId || undefined"
:dropdown-style="{ maxHeight: '360px', overflow: 'auto' }"
@update:value="(value?: number) => (form.parentId = value)"
/>
</a-form-item>
<a-form-item label="页面名称" name="title">
<a-input
allow-clear
placeholder="商品详情"
v-model:value="form.title"
/>
</a-form-item>
<a-form-item label="页面路径" name="path" :extra="pathExtra">
<a-input
allow-clear
placeholder="/package/goods/detail"
v-model:value="form.path"
/>
</a-form-item>
<a-form-item label="分包" name="subpackage">
<DictSelect
dict-code="mpPackage"
:placeholder="`选择分包`"
style="width: 200px"
v-model:value="form.subpackage"
@done="chooseSubpackage"
/>
</a-form-item>
<a-form-item label="图标" name="icon">
<SelectFile
:placeholder="`请选择图标`"
:limit="2"
:data="icon"
@done="chooseFile"
@del="onDeleteItem"
/>
</a-form-item>
<a-form-item label="排序" name="sortNumber">
<a-input-number
:min="0"
:max="99999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import {ref, reactive, watch} from 'vue';
import {Form, message} from 'ant-design-vue';
import {assignObject, uuid} from 'ele-admin-pro';
import {addCmsMpPages, updateCmsMpPages} from '@/api/cms/cmsMpPages';
import {CmsMpPages} from '@/api/cms/cmsMpPages/model';
import {useThemeStore} from '@/store/modules/theme';
import {storeToRefs} from 'pinia';
import {ItemType} from 'ele-admin-pro/es/ele-image-upload/types';
import {FormInstance} from 'ant-design-vue/es/form';
import {FileRecord} from '@/api/system/file/model';
import {DictData} from "@/api/system/dict-data/model";
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const {styleResponsive} = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 上级分类id
parentId?: number;
// 分包名称
packageName?: string;
// 修改回显的数据
data?: CmsMpPages | null;
// 页面列表
pages?: CmsMpPages[] | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const icon = ref<ItemType[]>([]);
const selectedIconPath = ref<ItemType[]>([]);
const pathExtra = ref<string>()
// 用户信息
const form = reactive<CmsMpPages>({
id: undefined,
parentId: undefined,
title: undefined,
path: undefined,
home: undefined,
subpackage: undefined,
icon: undefined,
iconPath: '',
selectedIconPath: '',
sortNumber: 100,
comments: undefined,
status: undefined
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
title: [
{
required: true,
type: 'string',
message: '页面名称',
trigger: 'blur'
}
],
path: [
{
required: true,
type: 'string',
message: '请填写路径',
trigger: 'blur'
}
],
subpackage: [
{
required: true,
type: 'string',
message: '请选择分包',
trigger: 'blur'
}
]
});
const chooseFile = (data: FileRecord) => {
icon.value.push({
uid: data.id,
url: data.downloadUrl,
status: 'done'
});
};
const onDeleteItem = (index: number) => {
icon.value.splice(index, 1);
};
const chooseSubpackage = (item: DictData) => {
form.subpackage = item.dictDataCode;
form.path = `/${form.subpackage}/`;
pathExtra.value = `请补填完整的页面路径`
}
const {resetFields} = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form,
icon: JSON.stringify(icon.value)
};
const saveOrUpdate = isUpdate.value ? updateCmsMpPages : addCmsMpPages;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {
});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
icon.value = [];
if (props.parentId) {
form.parentId = props.parentId;
}
if (props.data) {
assignObject(form, props.data);
if(props.data.icon){
const arr = JSON.parse(props.data.icon);
arr.map(d => {
icon.value.push({
uid: uuid(),
url: d.url,
status: 'done'
});
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{immediate: true}
);
</script>
<script lang="ts">
import * as icons from '@/layout/menu-icons';
export default {
components: icons,
data() {
return {
iconData: [
{
title: '已引入的图标',
icons: Object.keys(icons)
}
]
};
}
};
</script>

View File

@@ -1,66 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
<a-button type="dashed" class="ele-btn-icon" @click="expandAll">
展开
</a-button>
<a-button type="dashed" class="ele-btn-icon" @click="foldAll">
折叠
</a-button>
<a-input-search
allow-clear
v-model:value="where.keywords"
placeholder="请输入搜索关键词"
@search="search"
@pressEnter="search"
/>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import { watch } from 'vue';
import useSearch from '@/utils/use-search';
import { CmsMpPagesParam } from '@/api/cms/cmsMpPages/model';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
// 表单数据
const { where } = useSearch<CmsMpPagesParam>({
keywords: ''
});
const emit = defineEmits<{
(e: 'search', where?: CmsMpPagesParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
/* 搜索 */
const search = () => {
emit('search', where);
};
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,345 +0,0 @@
<template>
<a-page-header :title="getPageTitle()" @back="() => $router.go(-1)">
<template #extra>
<Extra/>
</template>
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="id"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
:parse-data="parseData"
:need-page="false"
:expand-icon-column-index="1"
:expanded-row-keys="expandedRowKeys"
tool-class="ele-toolbar-form"
class="sys-org-table"
cache-key="proCmsMpPagesTable"
@done="onDone"
@expand="onExpand"
>
<template #toolbar>
<a-space>
<a-button type="primary" class="ele-btn-icon" @click="openEdit()">
<template #icon>
<plus-outlined/>
</template>
<span>新建</span>
</a-button>
<a-button type="dashed" class="ele-btn-icon" @click="expandAll">
展开
</a-button>
<a-button type="dashed" class="ele-btn-icon" @click="foldAll">
折叠
</a-button>
<!-- 搜索表单 -->
<a-input-search
allow-clear
v-model:value="searchText"
placeholder="请输入搜索关键词"
@search="reload"
@pressEnter="reload"
/>
<a-button
type="text"
@click="openUrl('/mp-package')"
>分包管理
</a-button
>
<a-button type="text" class="ele-btn-icon" @click="clearSiteInfoCache">
清除缓存
</a-button>
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'title'">
{{ record.title }}
</template>
<template v-if="column.key === 'icon'">
<template v-if="record.icon" v-for="(item,index) in JSON.parse(record.icon)">
<a-image v-if="item.url" :id="index" :src="item.url" :width="50"/>
</template>
</template>
<template v-if="column.key === 'path'">
<span class="ele-text-placeholder">{{ record.path }}</span>
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'subpackage'">
<a-tag v-if="record.subpackage === 'pages'" color="orange"
>主包
</a-tag
>
<a-tag v-else> {{ record.subpackage }}</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(null, record.id,record.subpackage)">添加</a>
<!-- <a-divider type="vertical"/>-->
<!-- <a @click="openUrl(`/mp-field/${record.id}`)">参数</a>-->
<!-- <a-divider type="vertical"/>-->
<!-- <a @click="openUrl(`/mp-group/${record.id}`)">组件</a>-->
<!-- <a-divider type="vertical" />-->
<!-- <a @click="openUrl(`/mp-design/${record.id}`)">设计</a>-->
<a-divider type="vertical"/>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical"/>
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
<!-- <template #footer>-->
<!-- <div class="ele-text-secondary"-->
<!-- >页面设计可以替换图标和文字仓库地址http://git.gxwebsoft.com/websoft/nbg-uniapp.git</div-->
<!-- >-->
<!-- </template>-->
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<MpPagesEdit
v-model:visible="showEdit"
:parent-id="parentId"
:packageName="packageName"
:pages="pages"
:data="current"
@done="reload"
/>
</a-page-header>
</template>
<script lang="ts" setup>
import {createVNode, ref} from 'vue';
import {message, Modal} from 'ant-design-vue';
import {ExclamationCircleOutlined, PlusOutlined} from '@ant-design/icons-vue';
import type {EleProTable, toTreeData} from 'ele-admin-pro';
import {toDateString} from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem, EleProTableDone
} from 'ele-admin-pro/es/ele-pro-table/types';
import MpPagesEdit from './components/mpPagesEdit.vue';
import {
pageCmsMpPages,
removeCmsMpPages,
removeBatchCmsMpPages,
listCmsMpPages
} from '@/api/cms/cmsMpPages';
import type {CmsMpPages, CmsMpPagesParam} from '@/api/cms/cmsMpPages/model';
import {copyText, getPageTitle, openUrl} from '@/utils/common';
import Extra from "@/views/cms/cmsNavigation/components/extra.vue";
import {eachTreeData} from "ele-admin-pro/es";
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 页面列表
const pages = ref<CmsMpPages[]>([]);
// 表格选中数据
const selection = ref<CmsMpPages[]>([]);
// 上级分类id
const parentId = ref<number>();
// 当前编辑数据
const current = ref<CmsMpPages | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格展开的行
const expandedRowKeys = ref<number[]>([]);
// 当前选中的包
const packageName = ref<any>();
// 表格数据源
const datasource: DatasourceFunction = ({where}) => {
return listCmsMpPages({
...where
});
};
/* 表格渲染完成回调 */
const onDone: EleProTableDone<CmsMpPages> = ({data}) => {
pages.value = data;
};
/* 数据转为树形结构 */
const parseData = (data: CmsMpPages[]) => {
return toTreeData({
data: data.map((d) => {
return {...d, key: d.id, value: d.id};
}),
idField: 'id',
parentIdField: 'parentId'
});
};
/* 展开全部 */
const expandAll = () => {
let keys: number[] = [];
eachTreeData(pages.value, (d) => {
if (d.children && d.children.length && d.id) {
keys.push(d.id);
}
});
expandedRowKeys.value = keys;
};
/* 折叠全部 */
const foldAll = () => {
expandedRowKeys.value = [];
};
/* 点击展开图标时触发 */
const onExpand = (expanded: boolean, record: CmsMpPages) => {
if (expanded) {
expandedRowKeys.value = [
...expandedRowKeys.value,
record.id as number
];
} else {
expandedRowKeys.value = expandedRowKeys.value.filter(
(d) => d !== record.id
);
}
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
width: 80
},
{
title: '页面名称',
dataIndex: 'title',
key: 'title'
},
{
title: '页面路径',
dataIndex: 'path',
key: 'path'
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
sorter: true,
hideInTable: true,
ellipsis: true,
customRender: ({text}) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 280,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsMpPagesParam) => {
selection.value = [];
tableRef?.value?.reload({where: where});
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsMpPages | null, id?: number, mod?: string) => {
current.value = row ?? null;
packageName.value = mod ?? undefined;
parentId.value = id;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsMpPages) => {
const hide = message.loading('请求中..', 0);
removeCmsMpPages(row.id)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsMpPages(selection.value.map((d) => d.id))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsMpPages) => {
return {
// 行点击事件
onClick: () => {
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
import * as MenuIcons from '@/layout/menu-icons';
export default {
name: 'CmsMpPages',
components: MenuIcons
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,625 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑产品' : '添加产品'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-tabs type="card" v-model:active-key="active" @change="onChange">
<a-tab-pane tab="基本信息" key="base">
<a-form-item label="类型" name="title">
<a-radio-group v-model:value="form.type">
<a-radio-button :value="0"
>产品
</a-radio-button
>
<a-radio-button :value="1"
>插件
</a-radio-button
>
</a-radio-group>
</a-form-item>
<a-form-item label="所属栏目" name="categoryId">
<a-tree-select
allow-clear
:tree-data="navigationList"
tree-default-expand-all
placeholder="请选择栏目"
:value="form.categoryId || undefined"
:dropdown-style="{ maxHeight: '360px', overflow: 'auto' }"
@update:value="(value?: number) => (form.categoryId = value)"
/>
</a-form-item>
<a-form-item :label="`${form.type == 0 ? '产品' : '插件'}名称`" name="title">
<a-input
allow-clear
:placeholder="`内容管理系统`"
v-model:value="form.title"
/>
</a-form-item>
<a-form-item :label="`${form.type == 0 ? '产品' : '插件'}标识`" name="code">
<a-input
allow-clear
placeholder="cms"
v-model:value="form.code"
/>
</a-form-item>
<a-form-item :label="`${form.type == 0 ? '产品' : '插件'}描述`" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="基础模块,包含菜单、角色、用户、字典、支付、云存储、短信等配置"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item :label="`${form.type == 0 ? '产品' : '插件'}图标`" name="image">
<SelectFile
:placeholder="`请选择图片`"
:limit="1"
:data="images"
@done="chooseImage"
@del="onDeleteItem"
/>
</a-form-item>
<a-form-item :label="`${form.type == 0 ? '产品' : '插件'}截图`" name="files">
<SelectFile
:placeholder="`请选择视频文件`"
:limit="6"
:data="files"
@done="chooseFile"
@del="onDeleteFile"
/>
</a-form-item>
<template v-if="form.type === 1">
<a-divider style="margin-bottom: 20px"/>
<a-form-item :label="`关联菜单ID`" name="menuId">
<a-input-number
allow-clear
style="width: 220px"
placeholder="请输入管理菜单的ID"
v-model:value="form.menuId"
/>
</a-form-item>
</template>
<!-- <a-form-item :label="`插件入口`" name="path">-->
<!-- <a-input-->
<!-- allow-clear-->
<!-- placeholder="/system/menu"-->
<!-- v-model:value="form.path"-->
<!-- />-->
<!-- </a-form-item>-->
<a-divider style="margin-bottom: 20px"/>
<a-form-item label="单位" name="unitName">
<a-input
allow-clear
style="width: 220px"
placeholder="(套)"
v-model:value="form.unitName"
/>
</a-form-item>
<a-form-item label="价格" name="price">
<a-input-number
:min="0"
allow-clear
style="width: 220px"
placeholder="请输入销售价格"
v-model:value="form.price"
/>
</a-form-item>
<a-form-item label="库存" name="stock">
<a-input-number
allow-clear
style="width: 220px"
placeholder="请输入库存"
v-model:value="form.stock"
/>
</a-form-item>
<a-form-item label="排序号" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
style="width: 220px"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="交付方式" name="deliveryMethod">
<a-radio-group v-model:value="form.deliveryMethod">
<a-radio-button :value="0"
>不启用
</a-radio-button
>
<a-radio-button :value="1"
>SaaS交付
</a-radio-button
>
<a-radio-button :value="2"
>源码交付
</a-radio-button
>
</a-radio-group>
<!-- <a-space>-->
<!-- <div><a-switch v-model:checked="form.deliveryMethod" /></div>-->
<!-- <template v-if="form.deliveryMethod">-->
<!-- <span class="text-gray-400 px-4">字典名称deliveryMethod</span>-->
<!-- </template>-->
<!-- </a-space>-->
</a-form-item>
<a-form-item label="计费方式" name="durationMethod">
<a-radio-group v-model:value="form.durationMethod">
<a-radio-button :value="0"
>一次性
</a-radio-button
>
<a-radio-button :value="1"
>按年
</a-radio-button
>
<a-radio-button :value="2"
>按月
</a-radio-button
>
<a-radio-button :value="3"
>按天
</a-radio-button
>
</a-radio-group>
</a-form-item>
<a-form-item label="最多可购买数" name="canBuyNumber">
<a-input-number
allow-clear
style="width: 220px"
:min="1"
placeholder="最多可购买数量"
v-model:value="form.canBuyNumber"
/>
</a-form-item>
<a-form-item label="标签" name="tag">
<a-radio-group v-model:value="form.tag">
<a-radio-button value="0"
>不显示
</a-radio-button
>
<a-radio-button value="1"
>免费
</a-radio-button
>
<a-radio-button value="2"
>开源
</a-radio-button
>
<a-radio-button value="3"
>付费
</a-radio-button
>
</a-radio-group>
</a-form-item>
<a-form-item label="是否官方自营" name="official">
<a-switch
checked-children=""
un-checked-children=""
:checked="form.official"
@update:checked="updateOfficial"
/>
</a-form-item>
<a-form-item :label="`${form.type == 0 ? '产品' : '插件'}详情`" name="content">
<!-- 编辑器 -->
<tinymce-editor
ref="editorRef"
class="content"
v-model:value="content"
:disabled="disabled"
:init="config"
placeholder="图片直接粘贴自动上传"
@paste="onPaste"
/>
</a-form-item>
</a-tab-pane>
<template v-if="isUpdate">
<a-tab-pane tab="产品规格" key="spec">
<Spec :productId="form.productId"/>
</a-tab-pane>
<a-tab-pane tab="链接管理" key="links">
<CmsProductUrl :productId="form.productId"/>
</a-tab-pane>
<a-tab-pane tab="产品参数" key="parameter">
<CmsProductParameter :productId="form.productId"/>
</a-tab-pane>
<a-tab-pane tab="评论管理" key="comment">
<CmsProductComment :productId="form.productId"/>
</a-tab-pane>
</template>
</a-tabs>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import {ref, reactive, watch} from 'vue';
import {Form, message} from 'ant-design-vue';
import {assignObject, uuid} from 'ele-admin-pro';
import {addCmsProduct, updateCmsProduct} from '@/api/cms/cmsProduct';
import {CmsProduct} from '@/api/cms/cmsProduct/model';
import {useThemeStore} from '@/store/modules/theme';
import {storeToRefs} from 'pinia';
import {FormInstance, RuleObject} from 'ant-design-vue/es/form';
import {ItemType} from 'ele-admin-pro/es/ele-image-upload/types';
import {FileRecord} from '@/api/system/file/model';
import TinymceEditor from "@/components/TinymceEditor/index.vue";
import {uploadFile, uploadOss} from "@/api/system/file";
// import Spec from './spec.vue';
import CmsProductUrl from '@/views/cms/cmsProductUrl/index.vue';
import CmsProductParameter from '@/views/cms/cmsProductParameter/index.vue';
import CmsProductComment from '@/views/cms/cmsProductComment/index.vue';
import {Navigation} from "@/api/cms/navigation/model";
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const {styleResponsive} = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsProduct | null;
// 栏目数据
navigationList?: Navigation[];
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
const content = ref('');
const disabled = ref(false);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
const files = ref<ItemType[]>([]);
// 当前选项卡
const active = ref('base');
// 用户信息
const form = reactive<CmsProduct>({
productId: undefined,
type: 0,
code: undefined,
title: undefined,
image: undefined,
content: undefined,
parentId: 0,
parentName: '',
categoryId: 0,
categoryName: '',
menuId: 0,
path: undefined,
tag: undefined,
specs: undefined,
position: undefined,
unitName: undefined,
price: undefined,
salePrice: undefined,
deductStockType: undefined,
deliveryMethod: undefined,
durationMethod: 0,
serverMethod: undefined,
packageMethod: undefined,
canBuyNumber: 1,
files: undefined,
sales: undefined,
stock: 1000,
official: undefined,
gainIntegral: undefined,
recommend: undefined,
merchantId: undefined,
isShow: undefined,
status: undefined,
userId: undefined,
deleted: undefined,
tenantId: undefined,
createTime: undefined,
updateTime: undefined,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
categoryId: [
{
required: true,
type: 'number',
message: '请所属栏目',
trigger: 'blur'
}
],
title: [
{
required: true,
type: 'string',
message: '请填写产品名称',
trigger: 'blur'
}
],
code: [
{
required: true,
type: 'string',
message: '请填写产品/插件标识',
trigger: 'blur'
}
],
menuId: [
{
required: true,
type: 'number',
message: '请选择菜单ID',
trigger: 'blur'
}
],
path: [
{
required: true,
type: 'string',
message: '请填写插件入口地址',
trigger: 'blur'
}
],
price: [
{
required: true,
type: 'number',
message: '请填写产品价格',
trigger: 'blur'
}
],
stock: [
{
required: true,
type: 'number',
message: '请填写库存数量',
trigger: 'blur'
}
],
unitName: [
{
required: true,
type: 'string',
message: '请填写单位名称',
trigger: 'blur'
}
],
content: [
{
required: true,
type: "string",
message: "请输入产品详情",
trigger: "blur",
validator: async (_rule: RuleObject, value: string) => {
if (content.value == "") {
return Promise.reject("请输入文字内容");
}
return Promise.resolve();
}
}
],
comments: [
{
required: true,
type: 'string',
message: '请填写产品描述',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const chooseFile = (data: FileRecord) => {
files.value.push({
uid: data.id,
url: data.url,
status: 'done'
});
};
const onDeleteFile = (index: number) => {
files.value.splice(index, 1);
};
const updateOfficial = () => {
form.official = !form.official;
}
const onChange = () => {
// 加载多规格
form.productId = props.data?.productId
};
const editorRef = ref<InstanceType<typeof TinymceEditor> | null>(null);
const config = ref({
height: 500,
images_upload_handler: (blobInfo, success, error) => {
const file = blobInfo.blob();
const formData = new FormData();
formData.append('file', file, file.name);
uploadOss(file).then(res => {
success(res.path)
}).catch((msg) => {
error(msg);
})
},
// 自定义文件上传(这里使用把选择的文件转成 blob 演示)
file_picker_callback: (callback: any, _value: any, meta: any) => {
const input = document.createElement('input');
input.setAttribute('type', 'file');
// 设定文件可选类型
if (meta.filetype === 'image') {
input.setAttribute('accept', 'image/*');
} else if (meta.filetype === 'media') {
input.setAttribute('accept', 'video/*,.pdf');
}
input.onchange = () => {
const file = input.files?.[0];
if (!file) {
return;
}
if (meta.filetype === 'media') {
if (file.size / 1024 / 1024 > 200) {
editorRef.value?.alert({content: '大小不能超过 200MB'});
return;
}
if (file.type.startsWith('application/pdf')) {
uploadOss(file).then(res => {
const addPath = `<a href="${res.downloadUrl}" target="_blank">${res.name}</a>`;
content.value = content.value + addPath
})
return;
}
if (!file.type.startsWith('video/')) {
editorRef.value?.alert({content: '只能选择视频文件'});
return;
}
uploadOss(file).then(res => {
callback(res.path)
});
}
};
input.click();
}
});
/* 粘贴图片上传服务器并插入编辑器 */
const onPaste = (e) => {
const items = (e.clipboardData || e.originalEvent.clipboardData).items;
let hasFile = false;
for (let i = 0; i < items.length; i++) {
if (items[i].type.indexOf('image') !== -1) {
let file = items[i].getAsFile();
const item: ItemType = {
file,
uid: (file as any).lastModified,
name: file.name
};
uploadFile(<File>item.file)
.then((result) => {
const addPath = `<p><img class="content-img" src="${result.url}"></p>`;
content.value = content.value + addPath
})
.catch((e) => {
message.error(e.message);
});
hasFile = true;
}
}
if (hasFile) {
e.preventDefault();
}
}
const {resetFields} = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form,
content: content.value,
files: JSON.stringify(files.value),
};
const saveOrUpdate = isUpdate.value ? updateCmsProduct : addCmsProduct;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {
});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
files.value = [];
content.value = '';
if (props.data) {
assignObject(form, props.data);
if (props.data.image) {
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
});
}
if (props.data.files) {
files.value = JSON.parse(props.data.files);
}
if (props.data.content) {
content.value = props.data.content
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{immediate: true}
);
</script>

View File

@@ -1,190 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
<a-button
danger
type="primary"
class="ele-btn-icon"
:disabled="selection?.length === 0"
@click="removeBatch"
>
<template #icon>
<DeleteOutlined />
</template>
<span>批量删除</span>
</a-button>
<a-radio-group v-model:value="where.official" @change="handleSearch">
<a-radio-button :value="1"
>自营
</a-radio-button
>
<a-radio-button :value="0"
>市场
</a-radio-button
>
</a-radio-group>
<a-radio-group v-model:value="type" @change="handleSearch">
<a-radio-button :value="0"
>产品</a-radio-button
>
<a-radio-button :value="1"
>插件</a-radio-button
>
</a-radio-group>
<a-radio-group v-model:value="type" @change="handleSearch">
<a-radio-button value="已发布"
>已发布({{ articleCount?.totalNum }})</a-radio-button
>
<a-radio-button value="待审核"
>待审核({{ articleCount?.totalNum2 }})</a-radio-button
>
<a-radio-button value="已驳回"
>已驳回({{ articleCount?.totalNum3 }})</a-radio-button
>
</a-radio-group>
<a-tree-select
allow-clear
:tree-data="navigationList"
tree-default-expand-all
style="width: 280px"
placeholder="请选择栏目"
:value="where.categoryId || undefined"
:dropdown-style="{ maxHeight: '360px', overflow: 'auto' }"
@update:value="(value?: number) => (where.categoryId = value)"
@change="onCategoryId"
/>
<a-input-search
allow-clear
placeholder="请输入关键词"
style="width: 280px"
v-model:value="where.keywords"
@pressEnter="reload"
@search="reload"
/>
<a-button @click="reset">重置</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons-vue';
import { ref, watch } from 'vue';
import type { ArticleCount } from '@/api/cms/article/model';
import useSearch from '@/utils/use-search';
import { CmsNavigation } from '@/api/cms/cmsNavigation/model';
import { getCount } from '@/api/cms/cmsProduct';
import { CmsProductParam } from '@/api/cms/cmsProduct/model';
import { listCmsNavigation } from '@/api/cms/cmsNavigation';
import { toTreeData } from 'ele-admin-pro';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
merchantId?: number;
navigationList?: CmsNavigation[];
categoryId?: number;
model?: string;
}>(),
{}
);
const type = ref<string>();
// 统计数据
const articleCount = ref<ArticleCount>();
// 栏目数据
const navigationList = ref<CmsNavigation[]>();
// 表单数据
const { where, resetFields } = useSearch<CmsProductParam>({
productId: undefined,
type: undefined,
official: undefined,
status: undefined,
keywords: ''
});
const emit = defineEmits<{
(e: 'search', where?: CmsProductParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
// 批量删除
const removeBatch = () => {
emit('remove');
};
const handleSearch = (e) => {
const text = e.target.value;
if (text === '已发布') {
where.status = 0;
}
if (text === '待审核') {
where.status = 1;
}
if (text === '已驳回') {
where.status = 2;
}
where.type = text
emit('search', where);
};
const reload = () => {
emit('search', where);
};
// 按分类查询
const onCategoryId = (id: number) => {
where.categoryId = id;
emit('search', where);
};
/* 重置 */
const reset = () => {
resetFields();
type.value = undefined;
reload();
};
// 加载栏目数据
if (!navigationList.value) {
listCmsNavigation({}).then((res) => {
navigationList.value = toTreeData({
data: res?.map((d) => {
d.value = d.navigationId;
d.label = d.title;
return d;
}),
idField: 'navigationId',
parentIdField: 'parentId'
});
});
}
// 统计数据
getCount(where).then((data: any) => {
articleCount.value = data;
});
watch(
() => props.merchantId,
() => {
if (props.categoryId) {
where.categoryId = props.categoryId;
}
reload();
},
{ immediate: true }
);
</script>

View File

@@ -1,222 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-form-item label="交付方式" name="specs">
<a-radio-group v-model:value="form.specs">
<a-radio :value="0">单规格</a-radio>
</a-radio-group>
</a-form-item>
<a-radio-group v-model:value="form.deliveryMethod">
<a-radio-button :value="2"
>不限
</a-radio-button
>
<a-radio-button :value="0"
>SaaS交付
</a-radio-button
>
<a-radio-button :value="1"
>源码交付
</a-radio-button
>
</a-radio-group>
</template>
<script lang="ts" setup>
import {reactive, ref, watch} from 'vue';
import type {ArticleCount} from '@/api/cms/article/model';
import useSearch from '@/utils/use-search';
import {CmsNavigation} from '@/api/cms/cmsNavigation/model';
import {getCount} from '@/api/cms/cmsProduct';
import {CmsProduct, CmsProductParam} from '@/api/cms/cmsProduct/model';
import {listCmsNavigation} from '@/api/cms/cmsNavigation';
import {toTreeData} from 'ele-admin-pro';
import {CmsSpecValue} from "@/api/cms/cmsSpecValue/model";
import {GoodsSku} from "@/api/shop/goodsSku/model";
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
merchantId?: number;
navigationList?: CmsNavigation[];
categoryId?: number;
model?: string;
form?: CmsProduct;
}>(),
{}
);
const type = ref<string>();
// 统计数据
const articleCount = ref<ArticleCount>();
// 栏目数据
const navigationList = ref<CmsNavigation[]>();
const spec = ref<CmsSpecValue[]>([]);
const skuList = ref<GoodsSku[]>([]);
// 表单数据
const {where, resetFields} = useSearch<CmsProductParam>({
productId: undefined,
type: undefined,
status: undefined,
keywords: ''
});
const emit = defineEmits<{
(e: 'search', where?: CmsProductParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 用户信息
const form = reactive<CmsProduct>({
productId: undefined,
type: undefined,
code: undefined,
title: undefined,
image: undefined,
content: undefined,
parentId: undefined,
categoryId: 661,
menuId: undefined,
path: undefined,
specs: 0,
position: undefined,
unitName: undefined,
price: 0,
salePrice: undefined,
deductStockType: undefined,
files: undefined,
sales: undefined,
stock: undefined,
gainIntegral: undefined,
recommend: undefined,
merchantId: undefined,
isShow: undefined,
status: undefined,
userId: undefined,
deleted: undefined,
tenantId: undefined,
createTime: undefined,
updateTime: undefined,
comments: '',
sortNumber: 100
});
// 新增
const add = () => {
emit('add');
};
// 批量删除
const removeBatch = () => {
emit('remove');
};
const handleSearch = (e) => {
const text = e.target.value;
if (text === '已发布') {
where.status = 0;
}
if (text === '待审核') {
where.status = 1;
}
if (text === '已驳回') {
where.status = 2;
}
where.type = text
emit('search', where);
};
const reload = () => {
emit('search', where);
};
const chooseSkuImage = (data: FileRecord) => {
const index = data?.index;
skuList.value[index].images?.push({
uid: uuid(),
url: data.path,
status: 'done'
});
skuList.value[index].image = data.path;
}
const onDeleteSkuItem = (index: number) => {
images.value.splice(index, 1);
};
const onChange = (text: string) => {
// 加载商品多规格
if (text == 'spec') {
const goodsId = props.data?.goodsId;
if (goodsId) {
listGoodsSpec({goodsId}).then(data => {
const specValue = data[0].specValue;
if (specValue) {
spec.value = JSON.parse(specValue).map(d => {
console.log(d);
return {
value: d.value,
detail: d.detail
};
})
}
console.log(spec.value);
})
listGoodsSku({goodsId}).then(data => {
skuList.value = data;
})
}
}
};
const onSpec = (row: CmsSpec) => {
form.specName = row.specName;
goodsSpec.value = row;
if (row.specValue) {
spec.value = JSON.parse(row?.specValue);
}
}
/* 重置 */
const reset = () => {
resetFields();
type.value = undefined;
reload();
};
// 加载栏目数据
if (!navigationList.value) {
listCmsNavigation({}).then((res) => {
navigationList.value = toTreeData({
data: res?.map((d) => {
d.value = d.navigationId;
d.label = d.title;
return d;
}),
idField: 'navigationId',
parentIdField: 'parentId'
});
});
}
// 统计数据
getCount(where).then((data: any) => {
articleCount.value = data;
});
watch(
() => props.merchantId,
() => {
if (props.categoryId) {
where.categoryId = props.categoryId;
}
reload();
},
{immediate: true}
);
</script>

View File

@@ -1,356 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="productId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
v-model:selection="selection"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50"/>
</template>
<template v-if="column.key === 'title'">
<span
class="cursor-pointer"
@click="openSpmUrl(`/item`, record, record.productId)"
>{{ record.title }}</span
>
</template>
<template v-if="column.key ==='categoryName'">
<span class="cursor-pointer" @click="openSpmUrl(`/product`,record,record.categoryId, true)">{{ record.categoryName }}</span>
</template>
<template v-if="column.key === 'price'">
<span class="text-orange-500">{{ record.price }}</span>
</template>
<template v-if="column.key === 'salePrice'">
<span class="text-orange-500">{{ record.salePrice }}</span>
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green" class="cursor-pointer" @click="updateStatus(record)">
上架
</a-tag>
<a-tag v-if="record.status === 1" color="red" class="cursor-pointer" @click="updateStatus(record)">下架
</a-tag>
</template>
<template v-if="column.key === 'recommend'">
<a-space @click="onRecommend(record)">
<span v-if="record.recommend === 1" class="ele-text-success"
><CheckOutlined
/></span>
<span v-else class="ele-text-placeholder"><CloseOutlined/></span>
</a-space>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical"/>
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsProductEdit
v-model:visible="showEdit"
:data="current"
:navigationList="navigationList"
@done="reload"
/>
</div>
</div>
</template>
<script lang="ts" setup>
import {createVNode, ref} from 'vue';
import {message, Modal} from 'ant-design-vue';
import {CheckOutlined, CloseOutlined, ExclamationCircleOutlined} from '@ant-design/icons-vue';
import type {EleProTable, toTreeData} from 'ele-admin-pro';
import {toDateString} from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsProductEdit from './components/cmsProductEdit.vue';
import {
pageCmsProduct,
removeCmsProduct,
removeBatchCmsProduct, updateCmsProduct
} from '@/api/cms/cmsProduct';
import type {CmsProduct, CmsProductParam} from '@/api/cms/cmsProduct/model';
import {openSpmUrl} from '@/utils/common';
import {CmsNavigation} from "@/api/cms/cmsNavigation/model";
import {listCmsNavigation} from "@/api/cms/cmsNavigation";
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsProduct[]>([]);
// 当前编辑数据
const current = ref<CmsProduct | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 栏目数据
const navigationList = ref<CmsNavigation[]>();
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsProduct({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '编号',
dataIndex: 'productId',
key: 'productId',
align: 'center',
width: 90
},
{
title: '产品名称',
dataIndex: 'title',
key: 'title',
width: 280
},
{
title: '封面图',
dataIndex: 'image',
key: 'image',
align: 'center'
},
{
title: '所属栏目',
dataIndex: 'categoryName',
align: 'center',
key: 'categoryName'
},
{
title: '产品编码',
dataIndex: 'code',
key: 'code',
hideInTable: true,
align: 'center'
},
{
title: '单位',
dataIndex: 'unitName',
key: 'unitName',
align: 'center'
},
{
title: '进货价格',
dataIndex: 'price',
key: 'price',
align: 'center',
hideInTable: true
},
{
title: '销售价格',
dataIndex: 'salePrice',
key: 'salePrice',
align: 'center'
},
{
title: '销量',
dataIndex: 'sales',
key: 'sales',
align: 'center'
},
{
title: '推荐',
dataIndex: 'recommend',
key: 'recommend',
align: 'center'
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
align: 'center'
},
{
title: '排序',
dataIndex: 'sortNumber',
key: 'sortNumber',
align: 'center'
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({text}) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsProductParam) => {
selection.value = [];
tableRef?.value?.reload({where: where});
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsProduct) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsProduct) => {
const hide = message.loading('请求中..', 0);
removeCmsProduct(row.productId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsProduct(selection.value.map((d) => d.productId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
const onRecommend = (row: CmsProduct) => {
updateCmsProduct({
...row,
recommend: row.recommend == 1 ? 0 : 1
}).then((msg) => {
message.success(msg);
reload();
});
};
const updateStatus = (item: CmsProduct) => {
item.status = item.status === 1 ? 0 : 1
updateCmsProduct(item).then(res => {
message.success(res);
})
}
/* 查询 */
const query = () => {
loading.value = true;
// 加载栏目数据
if (!navigationList.value) {
listCmsNavigation({}).then((res) => {
navigationList.value = toTreeData({
data: res?.map((d) => {
d.value = d.navigationId;
d.label = d.title;
return d;
}),
idField: 'navigationId',
parentIdField: 'parentId'
});
});
}
};
/* 自定义行属性 */
const customRow = (record: CmsProduct) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsProduct'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,182 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑评论' : '添加评论'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="昵称" name="nickname">
{{ form.nickname }}
</a-form-item>
<a-form-item label="评论内容" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="状态" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="1">精选</a-radio>
<a-radio :value="0">普通</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsProductComment, updateCmsProductComment } from '@/api/cms/cmsProductComment';
import { CmsProductComment } from '@/api/cms/cmsProductComment/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsProductComment | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsProductComment>({
id: undefined,
productId: undefined,
userId: undefined,
nickname: undefined,
avatar: undefined,
image: undefined,
tenantId: undefined,
createTime: undefined,
status: 0,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsProductCommentName: [
{
required: true,
type: 'string',
message: '请填写产品评论名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsProductComment : addCmsProductComment;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,68 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-input-search
allow-clear
placeholder="请输入关键词"
v-model:value="where.keywords"
@pressEnter="search"
@search="search"
/>
<a-button
danger
type="primary"
class="ele-btn-icon"
:disabled="selection?.length === 0"
@click="removeBatch"
>
<template #icon>
<DeleteOutlined />
</template>
<span>批量删除</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import {watch} from 'vue';
import {CmsProductCommentParam} from "@/api/cms/cmsProductComment/model";
import useSearch from "@/utils/use-search";
import {DeleteOutlined} from "@ant-design/icons-vue";
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: CmsProductCommentParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 表单数据
const { where } = useSearch<CmsProductCommentParam>({
keywords: '',
userId: undefined
});
// 新增
const search = () => {
emit('search',where);
};
// 批量删除
const removeBatch = () => {
emit('remove');
};
watch(
() => props.selection,
() => {
}
);
</script>

View File

@@ -1,247 +0,0 @@
<template>
<ele-pro-table
ref="tableRef"
row-key="id"
:columns="columns"
:datasource="datasource"
v-model:selection="selection"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'nickname'">
<a-space class="flex ">
<span>{{ record.nickname }}</span>
</a-space>
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 1" color="green">精选</a-tag>
<a-tag v-if="record.status === 0">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
<!-- 编辑弹窗 -->
<CmsProductCommentEdit v-model:visible="showEdit" :data="current" @done="reload" />
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type {EleProTable, toTreeData} from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsProductCommentEdit from './components/cmsProductCommentEdit.vue';
import {
removeCmsProductComment,
removeBatchCmsProductComment,
listCmsProductComment, pageCmsProductComment
} from '@/api/cms/cmsProductComment';
import type { CmsProductComment, CmsProductCommentParam } from '@/api/cms/cmsProductComment/model';
const props = withDefaults(
defineProps<{
productId?: number;
}>(),
{}
);
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsProductComment[]>([]);
// 当前编辑数据
const current = ref<CmsProductComment | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
if(props.productId){
where.productId = props.productId;
}
return pageCmsProductComment({
...where,
...orders,
page,
limit
});
};
/* 数据转为树形结构 */
const parseData = (data: CmsProductComment[]) => {
return toTreeData({
data: data?.map((d) => {
return { ...d, key: d.userId, value: d.userId };
}),
idField: 'userId',
parentIdField: 'parentId'
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '昵称',
dataIndex: 'nickname',
key: 'nickname',
align: 'center',
},
{
title: '评论内容',
dataIndex: 'comments',
key: 'comments',
align: 'center',
},
{
title: '精选',
dataIndex: 'status',
key: 'status',
align: 'center',
},
{
title: '评论时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsProductCommentParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsProductComment) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsProductComment) => {
const hide = message.loading('请求中..', 0);
removeCmsProductComment(row.id)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsProductComment(selection.value.map((d) => d.id))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsProductComment) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsProductComment'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,183 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑产品参数' : '添加产品参数'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="参数名称" name="name">
<a-input
allow-clear
placeholder="开发语言"
v-model:value="form.name"
/>
</a-form-item>
<a-form-item label="参数内容" name="value">
<a-input
allow-clear
placeholder="Vue"
v-model:value="form.value"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="排序" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject } from 'ele-admin-pro';
import { addCmsProductParameter, updateCmsProductParameter } from '@/api/cms/cmsProductParameter';
import { CmsProductParameter } from '@/api/cms/cmsProductParameter/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 产品ID
productId?: number;
// 修改回显的数据
data?: CmsProductParameter | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsProductParameter>({
id: undefined,
productId: undefined,
name: undefined,
value: undefined,
comments: undefined,
createTime: undefined,
tenantId: undefined,
status: 0,
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
name: [
{
required: true,
type: 'string',
message: '请填写产品参数名称',
trigger: 'blur'
}
],
value: [
{
required: true,
type: 'string',
message: '请填写产品参数内容',
trigger: 'blur'
}
]
});
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form,
productId: props.productId
};
const saveOrUpdate = isUpdate.value ? updateCmsProductParameter : addCmsProductParameter;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,217 +0,0 @@
<template>
<ele-pro-table
ref="tableRef"
row-key="id"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
:need-page="false"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50"/>
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical"/>
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
<!-- 编辑弹窗 -->
<CmsProductParameterEdit v-model:visible="showEdit" :data="current" :productId="productId" @done="reload"/>
</template>
<script lang="ts" setup>
import {createVNode, ref} from 'vue';
import {message, Modal} from 'ant-design-vue';
import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
import type {EleProTable} from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsProductParameterEdit from './components/cmsProductParameterEdit.vue';
import {
pageCmsProductParameter,
removeCmsProductParameter,
removeBatchCmsProductParameter
} from '@/api/cms/cmsProductParameter';
import type {CmsProductParameter, CmsProductParameterParam} from '@/api/cms/cmsProductParameter/model';
const props = withDefaults(
defineProps<{
productId?: number;
}>(),
{}
);
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsProductParameter[]>([]);
// 当前编辑数据
const current = ref<CmsProductParameter | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
where.productId = props.productId;
return pageCmsProductParameter({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '参数名称',
dataIndex: 'name',
key: 'name',
align: 'center',
},
{
title: '参数内容',
dataIndex: 'value',
key: 'value',
align: 'center',
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsProductParameterParam) => {
selection.value = [];
tableRef?.value?.reload({where: where});
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsProductParameter) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsProductParameter) => {
const hide = message.loading('请求中..', 0);
removeCmsProductParameter(row.id)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsProductParameter(selection.value.map((d) => d.id))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsProductParameter) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsProductParameter'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,204 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑插件安装明细' : '添加插件安装明细'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="产品ID" name="productId">
<a-input
allow-clear
placeholder="请输入产品ID"
v-model:value="form.productId"
/>
</a-form-item>
<a-form-item label="用户ID" name="userId">
<a-input
allow-clear
placeholder="请输入用户ID"
v-model:value="form.userId"
/>
</a-form-item>
<a-form-item label="排序(数字越小越靠前)" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="状态, 0已安装, 1已卸载" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">显示</a-radio>
<a-radio :value="1">隐藏</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsProductRecord, updateCmsProductRecord } from '@/api/cms/cmsProductRecord';
import { CmsProductRecord } from '@/api/cms/cmsProductRecord/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsProductRecord | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsProductRecord>({
id: undefined,
productId: undefined,
userId: undefined,
sortNumber: undefined,
comments: undefined,
status: undefined,
tenantId: undefined,
createTime: undefined,
cmsProductRecordId: undefined,
cmsProductRecordName: '',
status: 0,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsProductRecordName: [
{
required: true,
type: 'string',
message: '请填写插件安装明细名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsProductRecord : addCmsProductRecord;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,245 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="cmsProductRecordId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsProductRecordEdit v-model:visible="showEdit" :data="current" @done="reload" />
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsProductRecordEdit from './components/cmsProductRecordEdit.vue';
import { pageCmsProductRecord, removeCmsProductRecord, removeBatchCmsProductRecord } from '@/api/cms/cmsProductRecord';
import type { CmsProductRecord, CmsProductRecordParam } from '@/api/cms/cmsProductRecord/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsProductRecord[]>([]);
// 当前编辑数据
const current = ref<CmsProductRecord | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsProductRecord({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
align: 'center',
width: 90,
},
{
title: '产品ID',
dataIndex: 'productId',
key: 'productId',
align: 'center',
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
align: 'center',
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
align: 'center',
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center',
},
{
title: '状态, 0已安装, 1已卸载',
dataIndex: 'status',
key: 'status',
align: 'center',
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsProductRecordParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsProductRecord) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsProductRecord) => {
const hide = message.loading('请求中..', 0);
removeCmsProductRecord(row.cmsProductRecordId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsProductRecord(selection.value.map((d) => d.cmsProductRecordId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsProductRecord) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsProductRecord'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,278 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑商品sku列表' : '添加商品sku列表'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="商品ID" name="goodsId">
<a-input
allow-clear
placeholder="请输入商品ID"
v-model:value="form.goodsId"
/>
</a-form-item>
<a-form-item label="商品属性索引值 (attr_value|attr_value[|....])" name="sku">
<a-input
allow-clear
placeholder="请输入商品属性索引值 (attr_value|attr_value[|....])"
v-model:value="form.sku"
/>
</a-form-item>
<a-form-item
label="商品图片"
name="image">
<SelectFile
:placeholder="`请选择图片`"
:limit="1"
:data="images"
@done="chooseImage"
@del="onDeleteItem"
/>
</a-form-item>
<a-form-item label="商品价格" name="price">
<a-input
allow-clear
placeholder="请输入商品价格"
v-model:value="form.price"
/>
</a-form-item>
<a-form-item label="市场价格" name="salePrice">
<a-input
allow-clear
placeholder="请输入市场价格"
v-model:value="form.salePrice"
/>
</a-form-item>
<a-form-item label="成本价" name="cost">
<a-input
allow-clear
placeholder="请输入成本价"
v-model:value="form.cost"
/>
</a-form-item>
<a-form-item label="库存" name="stock">
<a-input
allow-clear
placeholder="请输入库存"
v-model:value="form.stock"
/>
</a-form-item>
<a-form-item label="sku编码" name="skuNo">
<a-input
allow-clear
placeholder="请输入sku编码"
v-model:value="form.skuNo"
/>
</a-form-item>
<a-form-item label="商品条码" name="barCode">
<a-input
allow-clear
placeholder="请输入商品条码"
v-model:value="form.barCode"
/>
</a-form-item>
<a-form-item label="重量" name="weight">
<a-input
allow-clear
placeholder="请输入重量"
v-model:value="form.weight"
/>
</a-form-item>
<a-form-item label="体积" name="volume">
<a-input
allow-clear
placeholder="请输入体积"
v-model:value="form.volume"
/>
</a-form-item>
<a-form-item label="唯一值" name="uuid">
<a-input
allow-clear
placeholder="请输入唯一值"
v-model:value="form.uuid"
/>
</a-form-item>
<a-form-item label="状态, 0正常, 1异常" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">显示</a-radio>
<a-radio :value="1">隐藏</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsProductSku, updateCmsProductSku } from '@/api/cms/cmsProductSku';
import { CmsProductSku } from '@/api/cms/cmsProductSku/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsProductSku | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsProductSku>({
id: undefined,
goodsId: undefined,
sku: undefined,
image: undefined,
price: undefined,
salePrice: undefined,
cost: undefined,
stock: undefined,
skuNo: undefined,
barCode: undefined,
weight: undefined,
volume: undefined,
uuid: undefined,
status: undefined,
comments: undefined,
tenantId: undefined,
createTime: undefined,
cmsProductSkuId: undefined,
cmsProductSkuName: '',
status: 0,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsProductSkuName: [
{
required: true,
type: 'string',
message: '请填写商品sku列表名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsProductSku : addCmsProductSku;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,299 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="cmsProductSkuId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsProductSkuEdit v-model:visible="showEdit" :data="current" @done="reload" />
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsProductSkuEdit from './components/cmsProductSkuEdit.vue';
import { pageCmsProductSku, removeCmsProductSku, removeBatchCmsProductSku } from '@/api/cms/cmsProductSku';
import type { CmsProductSku, CmsProductSkuParam } from '@/api/cms/cmsProductSku/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsProductSku[]>([]);
// 当前编辑数据
const current = ref<CmsProductSku | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsProductSku({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '主键ID',
dataIndex: 'id',
key: 'id',
align: 'center',
width: 90,
},
{
title: '商品ID',
dataIndex: 'goodsId',
key: 'goodsId',
align: 'center',
},
{
title: '商品属性索引值 (attr_value|attr_value[|....])',
dataIndex: 'sku',
key: 'sku',
align: 'center',
},
{
title: '商品图片',
dataIndex: 'image',
key: 'image',
align: 'center',
},
{
title: '商品价格',
dataIndex: 'price',
key: 'price',
align: 'center',
},
{
title: '市场价格',
dataIndex: 'salePrice',
key: 'salePrice',
align: 'center',
},
{
title: '成本价',
dataIndex: 'cost',
key: 'cost',
align: 'center',
},
{
title: '库存',
dataIndex: 'stock',
key: 'stock',
align: 'center',
},
{
title: 'sku编码',
dataIndex: 'skuNo',
key: 'skuNo',
align: 'center',
},
{
title: '商品条码',
dataIndex: 'barCode',
key: 'barCode',
align: 'center',
},
{
title: '重量',
dataIndex: 'weight',
key: 'weight',
align: 'center',
},
{
title: '体积',
dataIndex: 'volume',
key: 'volume',
align: 'center',
},
{
title: '唯一值',
dataIndex: 'uuid',
key: 'uuid',
align: 'center',
},
{
title: '状态, 0正常, 1异常',
dataIndex: 'status',
key: 'status',
align: 'center',
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center',
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsProductSkuParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsProductSku) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsProductSku) => {
const hide = message.loading('请求中..', 0);
removeCmsProductSku(row.cmsProductSkuId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsProductSku(selection.value.map((d) => d.cmsProductSkuId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsProductSku) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsProductSku'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,220 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑规格' : '添加规格'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="规格名称" name="specName">
<a-input
allow-clear
placeholder="请输入规格名称"
v-model:value="form.specName"
/>
</a-form-item>
<a-form-item label="规格值" name="specValue">
<a-input
allow-clear
placeholder="请输入规格值"
v-model:value="form.specValue"
/>
</a-form-item>
<a-form-item label="创建用户" name="userId">
<a-input
allow-clear
placeholder="请输入创建用户"
v-model:value="form.userId"
/>
</a-form-item>
<a-form-item label="更新者" name="updater">
<a-input
allow-clear
placeholder="请输入更新者"
v-model:value="form.updater"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="状态, 0正常, 1待修,2异常已修3异常未修" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">显示</a-radio>
<a-radio :value="1">隐藏</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="排序号" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsProductSpec, updateCmsProductSpec } from '@/api/cms/cmsProductSpec';
import { CmsProductSpec } from '@/api/cms/cmsProductSpec/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsProductSpec | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsProductSpec>({
specId: undefined,
specName: undefined,
specValue: undefined,
userId: undefined,
updater: undefined,
comments: undefined,
status: undefined,
sortNumber: undefined,
tenantId: undefined,
createTime: undefined,
cmsProductSpecId: undefined,
cmsProductSpecName: '',
status: 0,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsProductSpecName: [
{
required: true,
type: 'string',
message: '请填写规格名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsProductSpec : addCmsProductSpec;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,257 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="cmsProductSpecId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsProductSpecEdit v-model:visible="showEdit" :data="current" @done="reload" />
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsProductSpecEdit from './components/cmsProductSpecEdit.vue';
import { pageCmsProductSpec, removeCmsProductSpec, removeBatchCmsProductSpec } from '@/api/cms/cmsProductSpec';
import type { CmsProductSpec, CmsProductSpecParam } from '@/api/cms/cmsProductSpec/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsProductSpec[]>([]);
// 当前编辑数据
const current = ref<CmsProductSpec | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsProductSpec({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '规格ID',
dataIndex: 'specId',
key: 'specId',
align: 'center',
width: 90,
},
{
title: '规格名称',
dataIndex: 'specName',
key: 'specName',
align: 'center',
},
{
title: '规格值',
dataIndex: 'specValue',
key: 'specValue',
align: 'center',
},
{
title: '创建用户',
dataIndex: 'userId',
key: 'userId',
align: 'center',
},
{
title: '更新者',
dataIndex: 'updater',
key: 'updater',
align: 'center',
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center',
},
{
title: '状态, 0正常, 1待修,2异常已修3异常未修',
dataIndex: 'status',
key: 'status',
align: 'center',
},
{
title: '排序号',
dataIndex: 'sortNumber',
key: 'sortNumber',
align: 'center',
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsProductSpecParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsProductSpec) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsProductSpec) => {
const hide = message.loading('请求中..', 0);
removeCmsProductSpec(row.cmsProductSpecId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsProductSpec(selection.value.map((d) => d.cmsProductSpecId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsProductSpec) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsProductSpec'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,197 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑规格值' : '添加规格值'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="规格组ID" name="specId">
<a-input
allow-clear
placeholder="请输入规格组ID"
v-model:value="form.specId"
/>
</a-form-item>
<a-form-item label="规格值" name="specValue">
<a-input
allow-clear
placeholder="请输入规格值"
v-model:value="form.specValue"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="排序号" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCmsProductSpecValue, updateCmsProductSpecValue } from '@/api/cms/cmsProductSpecValue';
import { CmsProductSpecValue } from '@/api/cms/cmsProductSpecValue/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsProductSpecValue | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsProductSpecValue>({
specValueId: undefined,
specId: undefined,
specValue: undefined,
comments: undefined,
sortNumber: undefined,
tenantId: undefined,
createTime: undefined,
cmsProductSpecValueId: undefined,
cmsProductSpecValueName: '',
status: 0,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
cmsProductSpecValueName: [
{
required: true,
type: 'string',
message: '请填写规格值名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCmsProductSpecValue : addCmsProductSpecValue;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,239 +0,0 @@
<template>
<div class="page">
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="cmsProductSpecValueId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CmsProductSpecValueEdit v-model:visible="showEdit" :data="current" @done="reload" />
</div>
</div>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsProductSpecValueEdit from './components/cmsProductSpecValueEdit.vue';
import { pageCmsProductSpecValue, removeCmsProductSpecValue, removeBatchCmsProductSpecValue } from '@/api/cms/cmsProductSpecValue';
import type { CmsProductSpecValue, CmsProductSpecValueParam } from '@/api/cms/cmsProductSpecValue/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsProductSpecValue[]>([]);
// 当前编辑数据
const current = ref<CmsProductSpecValue | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCmsProductSpecValue({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '规格值ID',
dataIndex: 'specValueId',
key: 'specValueId',
align: 'center',
width: 90,
},
{
title: '规格组ID',
dataIndex: 'specId',
key: 'specId',
align: 'center',
},
{
title: '规格值',
dataIndex: 'specValue',
key: 'specValue',
align: 'center',
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center',
},
{
title: '排序号',
dataIndex: 'sortNumber',
key: 'sortNumber',
align: 'center',
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsProductSpecValueParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsProductSpecValue) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsProductSpecValue) => {
const hide = message.loading('请求中..', 0);
removeCmsProductSpecValue(row.cmsProductSpecValueId)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsProductSpecValue(selection.value.map((d) => d.cmsProductSpecValueId))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsProductSpecValue) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsProductSpecValue'
};
</script>
<style lang="less" scoped></style>

View File

@@ -1,222 +0,0 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑链接' : '添加链接'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="名称" name="type">
<a-input
allow-clear
placeholder="演示地址"
v-model:value="form.type"
/>
</a-form-item>
<a-form-item label="内容" name="domain">
<a-input
allow-clear
placeholder="https://nbg-admin.websoft.top"
v-model:value="form.domain"
/>
</a-form-item>
<a-form-item label="账号" name="account">
<a-input
allow-clear
placeholder="请输入账号"
v-model:value="form.account"
/>
</a-form-item>
<a-form-item label="密码" name="password">
<a-input-password
allow-clear
placeholder="请输入密码"
v-model:value="form.password"
/>
</a-form-item>
<a-form-item label="二维码">
<SelectFile
:placeholder="`请选择图片`"
:limit="1"
:data="images"
@done="chooseImage"
@del="onDeleteItem"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
</a-form>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject } from 'ele-admin-pro';
import { addCmsProductUrl, updateCmsProductUrl } from '@/api/cms/cmsProductUrl';
import { CmsProductUrl } from '@/api/cms/cmsProductUrl/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import {FileRecord} from "@/api/system/file/model";
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CmsProductUrl | null;
// 产品ID
productId?: number;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CmsProductUrl>({
id: undefined,
productId: undefined,
type: undefined,
domain: undefined,
account: undefined,
password: undefined,
qrcode: undefined,
merchantId: undefined,
comments: undefined,
status: undefined,
createTime: undefined,
tenantId: undefined,
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
type: [
{
required: true,
type: 'string',
message: '请填写按钮名称',
trigger: 'blur'
}
],
domain: [
{
required: true,
type: 'string',
message: '请填写链接地址或上传图片',
trigger: 'blur'
}
]
});
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form,
productId: props?.productId
};
const saveOrUpdate = isUpdate.value ? updateCmsProductUrl : addCmsProductUrl;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.qrcode = data.downloadUrl;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.qrcode){
images.value.push({
uid: Number(props.data.id),
url: props.data.qrcode,
status: 'done'
});
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -1,42 +0,0 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -1,218 +0,0 @@
<template>
<ele-pro-table
ref="tableRef"
row-key="cmsProductUrlId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
:need-page="false"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'qrcode'">
<a-image :src="record.qrcode" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
<!-- 编辑弹窗 -->
<CmsProductUrlEdit v-model:visible="showEdit" :data="current" :productId="productId" @done="reload" />
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import CmsProductUrlEdit from './components/cmsProductUrlEdit.vue';
import { pageCmsProductUrl, removeCmsProductUrl, removeBatchCmsProductUrl } from '@/api/cms/cmsProductUrl';
import type { CmsProductUrl, CmsProductUrlParam } from '@/api/cms/cmsProductUrl/model';
const props = withDefaults(
defineProps<{
productId?: number;
}>(),
{}
);
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CmsProductUrl[]>([]);
// 当前编辑数据
const current = ref<CmsProductUrl | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
where.productId = props.productId;
return pageCmsProductUrl({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '名称',
dataIndex: 'type',
key: 'type',
align: 'center',
},
{
title: '内容',
dataIndex: 'domain',
key: 'domain',
align: 'center',
},
{
title: '二维码',
dataIndex: 'qrcode',
key: 'qrcode',
align: 'center',
},
{
title: '操作',
key: 'action',
width: 120,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CmsProductUrlParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CmsProductUrl) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CmsProductUrl) => {
const hide = message.loading('请求中..', 0);
removeCmsProductUrl(row.id)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCmsProductUrl(selection.value.map((d) => d.id))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CmsProductUrl) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CmsProductUrl'
};
</script>
<style lang="less" scoped></style>

Some files were not shown because too many files have changed in this diff Show More