Merge remote-tracking branch 'yudao/dev' into dev

This commit is contained in:
jason
2025-09-11 09:26:22 +08:00
961 changed files with 19066 additions and 28399 deletions

View File

@@ -21,8 +21,7 @@
// CSS 变量提示
"vunguyentuan.vscode-css-variables",
// 在 package.json 中显示 PNPM catalog 的版本
"antfu.pnpm-catalog-lens",
"augment.vscode-augment"
"antfu.pnpm-catalog-lens"
],
"unwantedRecommendations": [
// 和 volar 冲突

View File

@@ -50,12 +50,10 @@
"dayjs": "catalog:",
"highlight.js": "catalog:",
"pinia": "catalog:",
"tinymce": "catalog:",
"vue": "catalog:",
"vue-dompurify-html": "catalog:",
"vue-router": "catalog:",
"vue3-signature": "catalog:"
},
"devDependencies": {
"@types/crypto-js": "catalog:"
}
}

View File

@@ -22,6 +22,9 @@ const AutoComplete = defineAsyncComponent(
() => import('ant-design-vue/es/auto-complete'),
);
const Button = defineAsyncComponent(() => import('ant-design-vue/es/button'));
const Cascader = defineAsyncComponent(
() => import('ant-design-vue/es/cascader'),
);
const Checkbox = defineAsyncComponent(
() => import('ant-design-vue/es/checkbox'),
);
@@ -59,6 +62,9 @@ const Textarea = defineAsyncComponent(() =>
const TimePicker = defineAsyncComponent(
() => import('ant-design-vue/es/time-picker'),
);
const TimeRangePicker = defineAsyncComponent(() =>
import('ant-design-vue/es/time-picker').then((res) => res.TimeRangePicker),
);
const TreeSelect = defineAsyncComponent(
() => import('ant-design-vue/es/tree-select'),
);
@@ -100,6 +106,7 @@ const withDefaultPlaceholder = <T extends Component>(
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
export type ComponentType =
| 'ApiCascader'
| 'ApiSelect'
| 'ApiTreeSelect'
| 'AutoComplete'
@@ -126,6 +133,7 @@ export type ComponentType =
| 'Switch'
| 'Textarea'
| 'TimePicker'
| 'TimeRangePicker'
| 'TreeSelect'
| 'Upload'
| BaseFormComponentType;
@@ -135,6 +143,21 @@ async function initComponentAdapter() {
// 如果你的组件体积比较大,可以使用异步加载
// Button: () =>
// import('xxx').then((res) => res.Button),
ApiCascader: withDefaultPlaceholder(
{
...ApiComponent,
name: 'ApiCascader',
},
'select',
{
component: Cascader,
fieldNames: { label: 'label', value: 'value', children: 'children' },
loadingSlot: 'suffixIcon',
modelPropName: 'value',
optionsPropName: 'treeData',
visibleEvent: 'onVisibleChange',
},
),
ApiSelect: withDefaultPlaceholder(
{
...ApiComponent,
@@ -195,6 +218,7 @@ async function initComponentAdapter() {
Textarea: withDefaultPlaceholder(Textarea, 'input'),
RichTextarea,
TimePicker,
TimeRangePicker,
TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'),
Upload,
FileUpload,

View File

@@ -7,9 +7,7 @@ import type { ComponentType } from './component';
import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';
/** 手机号正则表达式(中国) */
const MOBILE_REGEX = /(?:0|86|\+86)?1[3-9]\d{9}/;
import { isMobile } from '@vben/utils';
async function initSetupVbenForm() {
setupVbenForm<ComponentType>({
@@ -44,7 +42,7 @@ async function initSetupVbenForm() {
mobile: (value, _params, ctx) => {
if (value === undefined || value === null || value.length === 0) {
return true;
} else if (!MOBILE_REGEX.test(value)) {
} else if (!isMobile(value)) {
return $t('ui.formRules.mobile', [ctx.label]);
}
return true;
@@ -54,7 +52,7 @@ async function initSetupVbenForm() {
if (value === undefined || value === null || value.length === 0) {
return $t('ui.formRules.required', [ctx.label]);
}
if (!MOBILE_REGEX.test(value)) {
if (!isMobile(value)) {
return $t('ui.formRules.mobile', [ctx.label]);
}
return true;

View File

@@ -1,79 +0,0 @@
/* 来自 @vben/plugins/vxe-table style.css覆盖 vxe-table 原有的样式定义,使用 vben 的样式主题 */
:root {
--vxe-ui-font-color: hsl(var(--foreground));
--vxe-ui-font-primary-color: hsl(var(--primary));
/* --vxe-ui-font-lighten-color: #babdc0;
--vxe-ui-font-darken-color: #86898e; */
--vxe-ui-font-disabled-color: hsl(var(--foreground) / 50%);
/* base */
--vxe-ui-base-popup-border-color: hsl(var(--border));
--vxe-ui-input-disabled-color: hsl(var(--border) / 60%);
/* --vxe-ui-base-popup-box-shadow: 0px 12px 30px 8px rgb(0 0 0 / 50%); */
/* layout */
--vxe-ui-layout-background-color: hsl(var(--background));
--vxe-ui-table-resizable-line-color: hsl(var(--heavy));
/* --vxe-ui-table-fixed-left-scrolling-box-shadow: 8px 0px 10px -5px hsl(var(--accent));
--vxe-ui-table-fixed-right-scrolling-box-shadow: -8px 0px 10px -5px hsl(var(--accent)); */
/* input */
--vxe-ui-input-border-color: hsl(var(--border));
/* --vxe-ui-input-placeholder-color: #8d9095; */
/* --vxe-ui-input-disabled-background-color: #262727; */
/* loading */
--vxe-ui-loading-background-color: hsl(var(--overlay-content));
/* table */
--vxe-ui-table-header-background-color: hsl(var(--accent));
--vxe-ui-table-border-color: hsl(var(--border));
--vxe-ui-table-row-hover-background-color: hsl(var(--accent-hover));
--vxe-ui-table-row-striped-background-color: hsl(var(--accent) / 60%);
--vxe-ui-table-row-hover-striped-background-color: hsl(var(--accent));
--vxe-ui-table-row-radio-checked-background-color: hsl(var(--accent));
--vxe-ui-table-row-hover-radio-checked-background-color: hsl(
var(--accent-hover)
);
--vxe-ui-table-row-checkbox-checked-background-color: hsl(var(--accent));
--vxe-ui-table-row-hover-checkbox-checked-background-color: hsl(
var(--accent-hover)
);
--vxe-ui-table-row-current-background-color: hsl(var(--accent));
--vxe-ui-table-row-hover-current-background-color: hsl(var(--accent-hover));
--vxe-ui-font-primary-tinge-color: hsl(var(--primary));
--vxe-ui-font-primary-lighten-color: hsl(var(--primary) / 60%);
--vxe-ui-font-primary-darken-color: hsl(var(--primary));
/* height: auto !important; */
/* --vxe-ui-table-fixed-scrolling-box-shadow-color: rgb(0 0 0 / 80%); */
}
.vxe-tools--operate {
margin-right: 0.25rem;
margin-left: 0.75rem;
}
.vxe-table-custom--checkbox-option:hover {
background: none !important;
}
.vxe-toolbar {
padding: 0;
}
.vxe-buttons--wrapper:not(:empty),
.vxe-tools--operate:not(:empty),
.vxe-tools--wrapper:not(:empty) {
padding: 0.6em 0;
}
.vxe-tools--operate:not(:has(button)) {
margin-left: 0;
}

View File

@@ -6,7 +6,8 @@ import { h } from 'vue';
import { IconifyIcon } from '@vben/icons';
import { $te } from '@vben/locales';
import {
AsyncComponents,
AsyncVxeColumn,
AsyncVxeTable,
createRequiredValidation,
setupVbenVxeTable,
useVbenVxeGrid,
@@ -34,8 +35,6 @@ import { $t } from '#/locales';
import { useVbenForm } from './form';
import '#/adapter/style.css';
setupVbenVxeTable({
configVxeTable: (vxeUI) => {
vxeUI.setConfig({
@@ -357,16 +356,8 @@ setupVbenVxeTable({
export { createRequiredValidation, useVbenVxeGrid };
const [VxeTable, VxeColumn, VxeToolbar] = AsyncComponents;
export { VxeColumn, VxeTable, VxeToolbar };
export const [VxeTable, VxeColumn] = [AsyncVxeTable, AsyncVxeColumn];
// add by 芋艿from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/adapter/vxe-table.ts#L264-L270
export type OnActionClickParams<T = Recordable<any>> = {
code: string;
row: T;
};
export type OnActionClickFn<T = Recordable<any>> = (
params: OnActionClickParams<T>,
) => void;
export * from '#/components/table-action';
export type * from '@vben/plugins/vxe-table';

View File

@@ -12,6 +12,7 @@ export namespace AiImageApi {
// AI 绘图
export interface Image {
id: number; // 编号
userId: number;
platform: string; // 平台
model: string; // 模型
prompt: string; // 提示词

View File

@@ -1,7 +1,6 @@
import type { AiWriteTypeEnum } from '@vben/constants';
import type { PageParam, PageResult } from '@vben/request';
import type { AiWriteTypeEnum } from '#/utils';
import { useAppConfig } from '@vben/hooks';
import { fetchEventSource } from '@vben/request';
import { useAccessStore } from '@vben/stores';

View File

@@ -1,57 +0,0 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace ProductUnitApi {
/** 产品单位信息 */
export interface ProductUnit {
id: number; // 编号
groupId?: number; // 分组编号
name?: string; // 单位名称
basic?: number; // 基础单位
number?: number; // 单位数量/相对于基础单位
usageType: number; // 用途
}
}
/** 查询产品单位分页 */
export function getProductUnitPage(params: PageParam) {
return requestClient.get<PageResult<ProductUnitApi.ProductUnit>>(
'/basic/product-unit/page',
{ params },
);
}
/** 查询产品单位详情 */
export function getProductUnit(id: number) {
return requestClient.get<ProductUnitApi.ProductUnit>(
`/basic/product-unit/get?id=${id}`,
);
}
/** 新增产品单位 */
export function createProductUnit(data: ProductUnitApi.ProductUnit) {
return requestClient.post('/basic/product-unit/create', data);
}
/** 修改产品单位 */
export function updateProductUnit(data: ProductUnitApi.ProductUnit) {
return requestClient.put('/basic/product-unit/update', data);
}
/** 删除产品单位 */
export function deleteProductUnit(id: number) {
return requestClient.delete(`/basic/product-unit/delete?id=${id}`);
}
/** 批量删除产品单位 */
export function deleteProductUnitListByIds(ids: number[]) {
return requestClient.delete(
`/basic/product-unit/delete-list?ids=${ids.join(',')}`,
);
}
/** 导出产品单位 */
export function exportProductUnit(params: any) {
return requestClient.download('/basic/product-unit/export-excel', params);
}

View File

@@ -1,61 +0,0 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace ProductUnitGroupApi {
/** 产品单位组信息 */
export interface ProductUnitGroup {
id: number; // 编号
name?: string; // 产品单位组名称
status?: number; // 开启状态
}
}
/** 查询产品单位组分页 */
export function getProductUnitGroupPage(params: PageParam) {
return requestClient.get<PageResult<ProductUnitGroupApi.ProductUnitGroup>>(
'/basic/product-unit-group/page',
{ params },
);
}
/** 查询产品单位组详情 */
export function getProductUnitGroup(id: number) {
return requestClient.get<ProductUnitGroupApi.ProductUnitGroup>(
`/basic/product-unit-group/get?id=${id}`,
);
}
/** 新增产品单位组 */
export function createProductUnitGroup(
data: ProductUnitGroupApi.ProductUnitGroup,
) {
return requestClient.post('/basic/product-unit-group/create', data);
}
/** 修改产品单位组 */
export function updateProductUnitGroup(
data: ProductUnitGroupApi.ProductUnitGroup,
) {
return requestClient.put('/basic/product-unit-group/update', data);
}
/** 删除产品单位组 */
export function deleteProductUnitGroup(id: number) {
return requestClient.delete(`/basic/product-unit-group/delete?id=${id}`);
}
/** 批量删除产品单位组 */
export function deleteProductUnitGroupListByIds(ids: number[]) {
return requestClient.delete(
`/basic/product-unit-group/delete-list?ids=${ids.join(',')}`,
);
}
/** 导出产品单位组 */
export function exportProductUnitGroup(params: any) {
return requestClient.download(
'/basic/product-unit-group/export-excel',
params,
);
}

View File

@@ -49,5 +49,7 @@ export async function deleteProcessExpression(id: number) {
/** 导出流程表达式 */
export async function exportProcessExpression(params: any) {
return requestClient.download('/bpm/process-expression/export-excel', params);
return requestClient.download('/bpm/process-expression/export-excel', {
params,
});
}

View File

@@ -1,9 +1,12 @@
import type {
BpmCandidateStrategyEnum,
BpmNodeTypeEnum,
} from '@vben/constants';
import type { PageParam, PageResult } from '@vben/request';
import type { BpmTaskApi } from '../task';
import type { BpmModelApi } from '#/api/bpm/model';
import type { BpmCandidateStrategyEnum, BpmNodeTypeEnum } from '#/utils';
import { requestClient } from '#/api/request';

View File

@@ -133,5 +133,7 @@ export const getChildrenTaskList = async (id: string) => {
// 撤回任务
export const withdrawTask = async (taskId: string) => {
return await requestClient.put('/bpm/task/withdraw', null, { params: { taskId } });
return await requestClient.put('/bpm/task/withdraw', null, {
params: { taskId },
});
};

View File

@@ -108,7 +108,7 @@ export function deleteBusiness(id: number) {
/** 导出商机 */
export function exportBusiness(params: any) {
return requestClient.download('/crm/business/export-excel', params);
return requestClient.download('/crm/business/export-excel', { params });
}
/** 联系人关联商机列表 */

View File

@@ -67,7 +67,7 @@ export function deleteClue(id: number) {
/** 导出线索 */
export function exportClue(params: any) {
return requestClient.download('/crm/clue/export-excel', params);
return requestClient.download('/crm/clue/export-excel', { params });
}
/** 线索转移 */

View File

@@ -96,7 +96,7 @@ export function deleteContact(id: number) {
/** 导出联系人 */
export function exportContact(params: any) {
return requestClient.download('/crm/contact/export-excel', params);
return requestClient.download('/crm/contact/export-excel', { params });
}
/** 获得联系人列表(精简) */

View File

@@ -108,7 +108,7 @@ export function deleteContract(id: number) {
/** 导出合同 */
export function exportContract(params: any) {
return requestClient.download('/crm/contract/export-excel', params);
return requestClient.download('/crm/contract/export-excel', { params });
}
/** 提交审核 */

View File

@@ -74,7 +74,7 @@ export function deleteCustomer(id: number) {
/** 导出客户 */
export function exportCustomer(params: any) {
return requestClient.download('/crm/customer/export-excel', params);
return requestClient.download('/crm/customer/export-excel', { params });
}
/** 下载客户导入模板 */

View File

@@ -53,5 +53,5 @@ export function deleteProduct(id: number) {
/** 导出产品 */
export function exportProduct(params: any) {
return requestClient.download('/crm/product/export-excel', params);
return requestClient.download('/crm/product/export-excel', { params });
}

View File

@@ -89,7 +89,7 @@ export function deleteReceivable(id: number) {
/** 导出回款 */
export function exportReceivable(params: any) {
return requestClient.download('/crm/receivable/export-excel', params);
return requestClient.download('/crm/receivable/export-excel', { params });
}
/** 提交审核 */

View File

@@ -2,19 +2,45 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
namespace ErpPurchaseInApi {
export namespace ErpPurchaseInApi {
/** 采购入库信息 */
export interface PurchaseIn {
id?: number; // 入库工单编号
no: string; // 采购入库号
supplierId: number; // 供应商编号
inTime: Date; // 入库时间
totalCount: number; // 合计数量
totalPrice: number; // 合计金额,单位:元
status: number; // 状态
remark: string; // 备注
outCount: number; // 采购出库数量
returnCount: number; // 采购退货数量
no?: string; // 采购入库号
supplierId?: number; // 供应商编号
inTime?: Date; // 入库时间
totalCount?: number; // 合计数量
totalPrice?: number; // 合计金额,单位:元
status?: number; // 状态
remark?: string; // 备注
outCount?: number; // 采购出库数量
returnCount?: number; // 采购退货数量
discountPercent?: number; // 折扣百分比
discountPrice?: number; // 折扣金额
paymentPrice?: number; // 实际支付金额
otherPrice?: number; // 其他费用
totalProductPrice?: number; // 合计商品金额
taxPrice?: number; // 合计税额
items?: PurchaseInItem[]; // 采购入库明细
}
export interface PurchaseInItem {
count?: number;
id?: number;
orderItemId?: number;
productBarCode?: string;
productId?: number;
productName: string;
productPrice: number;
productUnitId?: number;
productUnitName?: string;
totalProductPrice?: number;
remark: string;
stockCount?: number;
taxPercent?: number;
taxPrice?: number;
totalPrice?: number;
warehouseId?: number;
inCount?: number;
}
/** 采购入库分页查询参数 */
@@ -24,6 +50,7 @@ namespace ErpPurchaseInApi {
status?: number;
}
// TODO @nehcupdatePurchaseInStatus 是不是需要?
/** 采购入库状态更新参数 */
export interface PurchaseInStatusParams {
id: number;
@@ -71,11 +98,12 @@ export function updatePurchaseIn(data: ErpPurchaseInApi.PurchaseIn) {
/**
* 更新采购入库的状态
*/
export function updatePurchaseInStatus(
params: ErpPurchaseInApi.PurchaseInStatusParams,
) {
export function updatePurchaseInStatus(id: number, status: number) {
return requestClient.put('/erp/purchase-in/update-status', null, {
params,
params: {
id,
status,
},
});
}

View File

@@ -41,6 +41,7 @@ export namespace ErpPurchaseOrderApi {
remark?: string; // 备注
fileUrl?: string; // 附件地址
inCount?: number; // 采购入库数量
count?: number; // 数量
returnCount?: number; // 采购退货数量
inStatus?: number; // 入库状态
returnStatus?: number; // 退货状态

View File

@@ -2,17 +2,40 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
namespace ErpPurchaseReturnApi {
export namespace ErpPurchaseReturnApi {
/** 采购退货信息 */
export interface PurchaseReturn {
id?: number; // 采购退货编号
no: string; // 采购退货号
supplierId: number; // 供应商编号
returnTime: Date; // 退货时间
totalCount: number; // 合计数量
no?: string; // 采购退货号
supplierId?: number; // 供应商编号
returnTime?: Date; // 退货时间
totalCount?: number; // 合计数量
totalPrice: number; // 合计金额,单位:元
status: number; // 状态
remark: string; // 备注
discountPercent?: number; // 折扣百分比
discountPrice?: number; // 折扣金额
status?: number; // 状态
remark?: string; // 备注
totalTaxPrice?: number; // 合计税额
otherPrice?: number; // 其他费用
items?: PurchaseReturnItem[];
}
export interface PurchaseReturnItem {
count?: number;
id?: number;
orderItemId?: number;
productBarCode?: string;
productId?: number;
productName: string;
productPrice: number;
productUnitId?: number;
productUnitName?: string;
totalProductPrice?: number;
remark: string;
stockCount?: number;
taxPercent?: number;
taxPrice?: number;
totalPrice?: number;
warehouseId?: number;
}
/** 采购退货分页查询参数 */

View File

@@ -8,13 +8,39 @@ export namespace ErpSaleOrderApi {
id?: number; // 订单工单编号
no: string; // 销售订单号
customerId: number; // 客户编号
accountId?: number; // 收款账户编号
orderTime: Date; // 订单时间
totalCount: number; // 合计数量
totalPrice: number; // 合计金额,单位:元
status: number; // 状态
remark: string; // 备注
outCount: number; // 销售出库数量
fileUrl?: string; // 附件地址
inCount?: number; // 采购入库数量
returnCount: number; // 销售退货数量
totalProductPrice?: number; // 产品金额,单位:元
discountPercent?: number; // 优惠率,百分比
discountPrice?: number; // 优惠金额,单位:元
depositPrice?: number; // 定金金额,单位:元
items?: SaleOrderItem[]; // 销售订单产品明细列表
}
export interface SaleOrderItem {
id?: number; // 订单项编号
orderId?: number; // 采购订单编号
productId?: number; // 产品编号
productName?: string; // 产品名称
productBarCode?: string; // 产品条码
productUnitId?: number; // 产品单位编号
productUnitName?: string; // 产品单位名称
productPrice?: number; // 产品单价,单位:元
totalProductPrice?: number; // 产品总价,单位:元
count?: number; // 数量
totalPrice?: number; // 总价,单位:元
taxPercent?: number; // 税率,百分比
taxPrice?: number; // 税额,单位:元
totalTaxPrice?: number; // 含税总价,单位:元
remark?: string; // 备注
stockCount?: number; // 库存数量(显示字段)
}
/** 销售订单分页查询参数 */

View File

@@ -2,17 +2,45 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
namespace ErpSaleOutApi {
export namespace ErpSaleOutApi {
/** 销售出库信息 */
export interface SaleOut {
id?: number; // 销售出库编号
no: string; // 销售出库号
customerId: number; // 客户编号
outTime: Date; // 出库时间
totalCount: number; // 合计数量
totalPrice: number; // 合计金额,单位:元
status: number; // 状态
remark: string; // 备注
no?: string; // 销售出库号
customerId?: number; // 客户编号
saleUserId?: number; // 客户编号
outTime?: Date; // 出库时间
totalCount?: number; // 合计数量
totalPrice?: number; // 合计金额,单位:元
status?: number; // 状态
remark?: string; // 备注
discountPercent?: number; // 折扣百分比
discountPrice?: number; // 折扣金额
otherPrice?: number; // 其他费用
totalProductPrice?: number; // 合计商品金额
taxPrice?: number; // 合计税额
totalTaxPrice?: number; // 合计税额
fileUrl?: string; // 附件地址
items?: SaleOutItem[];
}
export interface SaleOutItem {
count?: number;
id?: number;
orderItemId?: number;
productBarCode?: string;
productId?: number;
productName: string;
productPrice: number;
productUnitId?: number;
productUnitName?: string;
totalProductPrice?: number;
remark: string;
stockCount?: number;
taxPercent?: number;
taxPrice?: number;
totalPrice?: number;
warehouseId?: number;
outCount?: number;
}
/** 销售出库分页查询参数 */

View File

@@ -2,17 +2,44 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
namespace ErpSaleReturnApi {
export namespace ErpSaleReturnApi {
/** 销售退货信息 */
export interface SaleReturn {
id?: number; // 销售退货编号
no: string; // 销售退货号
customerId: number; // 客户编号
returnTime: Date; // 退货时间
totalCount: number; // 合计数量
totalPrice: number; // 合计金额,单位:元
status: number; // 状态
remark: string; // 备注
no?: string; // 销售退货号
customerId?: number; // 客户编号
returnTime?: Date; // 退货时间
totalCount?: number; // 合计数量
totalPrice?: number; // 合计金额,单位:元
status?: number; // 状态
remark?: string; // 备注
discountPercent?: number; // 折扣百分比
discountPrice?: number; // 折扣金额
otherPrice?: number; // 其他费用
totalProductPrice?: number; // 合计商品金额
taxPrice?: number; // 合计税额
totalTaxPrice?: number; // 合计税额
fileUrl?: string; // 附件地址
items?: SaleReturnItem[];
}
export interface SaleReturnItem {
count?: number;
id?: number;
orderItemId?: number;
productBarCode?: string;
productId?: number;
productName: string;
productPrice: number;
productUnitId?: number;
productUnitName?: string;
totalProductPrice?: number;
remark: string;
stockCount?: number;
taxPercent?: number;
taxPrice?: number;
totalPrice?: number;
warehouseId?: number;
returnCount?: number;
}
/** 销售退货分页查询参数 */

View File

@@ -2,7 +2,7 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
namespace ErpStockCheckApi {
export namespace ErpStockCheckApi {
/** 库存盘点单信息 */
export interface StockCheck {
id?: number; // 盘点编号
@@ -12,6 +12,25 @@ namespace ErpStockCheckApi {
totalPrice: number; // 合计金额,单位:元
status: number; // 状态
remark: string; // 备注
fileUrl?: string; // 附件
productNames?: string; // 产品信息
creatorName?: string; // 创建人
items?: StockCheckItem[]; // 盘点产品清单
}
export interface StockCheckItem {
id?: number; // 编号
warehouseId?: number; // 仓库编号
productId?: number; // 产品编号
productName?: string; // 产品名称
productUnitId?: number; // 产品单位编号
productUnitName?: string; // 产品单位名称
productBarCode?: string; // 产品条码
count?: number; // 盈亏数量
actualCount?: number; // 实际库存
productPrice?: number; // 产品单价
totalPrice?: number; // 总价
stockCount?: number; // 账面库存
remark?: string; // 备注
}
/** 库存盘点单分页查询参数 */

View File

@@ -2,7 +2,7 @@ import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
namespace ErpStockMoveApi {
export namespace ErpStockMoveApi {
/** 库存调拨单信息 */
export interface StockMove {
id?: number; // 调拨编号
@@ -12,6 +12,29 @@ namespace ErpStockMoveApi {
totalPrice: number; // 合计金额,单位:元
status: number; // 状态
remark: string; // 备注
fileUrl?: string; // 附件
fromWarehouseId?: number; // 来源仓库编号
createTime: Date; // 创建时间
creator: string; // 创建人
creatorName: string; // 创建人名称
productNames: string; // 产品名称
items?: StockMoveItem[]; // 子表信息
}
/** 库存调拨单子表信息 */
export interface StockMoveItem {
count: number; // 数量
fromWarehouseId?: number; // 来源仓库ID
id?: number; // ID
productBarCode: string; // 产品条形码
productId?: number; // 产品ID
productName?: string; // 产品名称
productPrice: number; // 产品单价
productUnitName?: string; // 产品单位
remark?: string; // 备注
stockCount: number; // 库存数量
toWarehouseId?: number; // 目标仓库ID
totalPrice?: number; // 总价
}
/** 库存调拨单分页查询参数 */

View File

@@ -72,3 +72,12 @@ export function exportStock(params: ErpStockApi.StockPageParams) {
params,
});
}
/**
* 获取库存数量
*/
export function getWarehouseStockCount(params: ErpStockApi.StockQueryParams) {
return requestClient.get<number>('/erp/stock/get-count', {
params,
});
}

View File

@@ -71,7 +71,7 @@ export namespace InfraCodegenApi {
}
/** 创建代码生成请求 */
export interface CodegenCreateListReq {
export interface CodegenCreateListReqVO {
dataSourceConfigId?: number;
tableNames: string[];
}
@@ -136,7 +136,7 @@ export function getSchemaTableList(params: any) {
}
/** 基于数据库的表结构,创建代码生成器的表定义 */
export function createCodegenList(data: InfraCodegenApi.CodegenCreateListReq) {
export function createCodegenList(data: InfraCodegenApi.CodegenCreateListReqVO) {
return requestClient.post('/infra/codegen/create-list', data);
}

View File

@@ -55,5 +55,7 @@ export function deleteDemo01ContactList(ids: number[]) {
/** 导出示例联系人 */
export function exportDemo01Contact(params: any) {
return requestClient.download('/infra/demo01-contact/export-excel', params);
return requestClient.download('/infra/demo01-contact/export-excel', {
params,
});
}

View File

@@ -42,5 +42,7 @@ export function deleteDemo02Category(id: number) {
/** 导出示例分类 */
export function exportDemo02Category(params: any) {
return requestClient.download('/infra/demo02-category/export-excel', params);
return requestClient.download('/infra/demo02-category/export-excel', {
params,
});
}

View File

@@ -70,10 +70,9 @@ export function deleteDemo03StudentList(ids: number[]) {
/** 导出学生 */
export function exportDemo03Student(params: any) {
return requestClient.download(
'/infra/demo03-student-erp/export-excel',
return requestClient.download('/infra/demo03-student-erp/export-excel', {
params,
);
});
}
// ==================== 子表(学生课程) ====================

View File

@@ -72,10 +72,9 @@ export function deleteDemo03StudentList(ids: number[]) {
/** 导出学生 */
export function exportDemo03Student(params: any) {
return requestClient.download(
'/infra/demo03-student-inner/export-excel',
return requestClient.download('/infra/demo03-student-inner/export-excel', {
params,
);
});
}
// ==================== 子表(学生课程) ====================

View File

@@ -72,10 +72,9 @@ export function deleteDemo03StudentList(ids: number[]) {
/** 导出学生 */
export function exportDemo03Student(params: any) {
return requestClient.download(
'/infra/demo03-student-normal/export-excel',
return requestClient.download('/infra/demo03-student-normal/export-excel', {
params,
);
});
}
// ==================== 子表(学生课程) ====================

View File

@@ -113,6 +113,8 @@ export namespace MallSpuApi {
createTime?: Date;
/** 商品状态 */
status?: number;
/** 浏览量 */
browseCount?: number;
}
/** 商品状态更新 */

View File

@@ -31,6 +31,8 @@ export namespace MallDeliveryPickUpStoreApi {
status: number;
/** 绑定用户编号组数 */
verifyUserIds: number[];
/** 营业时间 用于fieldMappingTime */
rangeTime: any[];
}
/** 绑定自提店员请求 */

View File

@@ -16,6 +16,7 @@ export namespace PayAppApi {
merchantId: number;
merchantName: string;
createTime?: Date;
channelCodes: string[];
}
/** 更新状态请求 */

View File

@@ -19,7 +19,7 @@ export namespace SystemMailTemplateApi {
}
/** 邮件发送信息 */
export interface MailSendReq {
export interface MailSendReqVO {
toMails: string[];
ccMails?: string[];
bccMails?: string[];
@@ -66,6 +66,6 @@ export function deleteMailTemplateList(ids: number[]) {
}
/** 发送邮件 */
export function sendMail(data: SystemMailTemplateApi.MailSendReq) {
export function sendMail(data: SystemMailTemplateApi.MailSendReqVO) {
return requestClient.post('/system/mail-template/send-mail', data);
}

View File

@@ -17,7 +17,7 @@ export namespace SystemNotifyTemplateApi {
}
/** 发送站内信请求 */
export interface NotifySendReq {
export interface NotifySendReqVO {
userId: number;
userType: number;
templateCode: string;
@@ -74,6 +74,6 @@ export function exportNotifyTemplate(params: any) {
}
/** 发送站内信 */
export function sendNotify(data: SystemNotifyTemplateApi.NotifySendReq) {
export function sendNotify(data: SystemNotifyTemplateApi.NotifySendReqVO) {
return requestClient.post('/system/notify-template/send-notify', data);
}

View File

@@ -55,3 +55,10 @@ export function updateOAuth2Client(data: SystemOAuth2ClientApi.OAuth2Client) {
export function deleteOAuth2Client(id: number) {
return requestClient.delete(`/system/oauth2-client/delete?id=${id}`);
}
/** 批量删除 OAuth2.0 客户端 */
export function deleteOAuth2ClientList(ids: number[]) {
return requestClient.delete(
`/system/oauth2-client/delete-list?ids=${ids.join(',')}`,
);
}

View File

@@ -20,7 +20,7 @@ export namespace SystemSmsTemplateApi {
}
/** 发送短信请求 */
export interface SmsSendReq {
export interface SmsSendReqVO {
mobile: string;
templateCode: string;
templateParams: Record<string, any>;
@@ -72,6 +72,6 @@ export function exportSmsTemplate(params: any) {
}
/** 发送短信 */
export function sendSms(data: SystemSmsTemplateApi.SmsSendReq) {
export function sendSms(data: SystemSmsTemplateApi.SmsSendReqVO) {
return requestClient.post('/system/sms-template/send-sms', data);
}

View File

@@ -46,3 +46,10 @@ export function updateSocialClient(data: SystemSocialClientApi.SocialClient) {
export function deleteSocialClient(id: number) {
return requestClient.delete(`/system/social-client/delete?id=${id}`);
}
/** 批量删除社交客户端 */
export function deleteSocialClientList(ids: number[]) {
return requestClient.delete(
`/system/social-client/delete-list?ids=${ids.join(',')}`,
);
}

View File

@@ -56,7 +56,7 @@ export function deleteUserList(ids: number[]) {
/** 导出用户 */
export function exportUser(params: any) {
return requestClient.download('/system/user/export-excel', params);
return requestClient.download('/system/user/export-excel', { params });
}
/** 下载用户导入模板 */

View File

@@ -1,73 +0,0 @@
<script setup lang="ts">
import type { Item } from './ui/typing';
import { onMounted, onUnmounted, ref } from 'vue';
import { Tinyflow as TinyflowNative } from './ui/index';
import './ui/index.css';
const props = defineProps<{
className?: string;
data?: Record<string, any>;
provider?: {
internal?: () => Item[] | Promise<Item[]>;
knowledge?: () => Item[] | Promise<Item[]>;
llm?: () => Item[] | Promise<Item[]>;
};
style?: Record<string, string>;
}>();
const divRef = ref<HTMLDivElement | null>(null);
let tinyflow: null | TinyflowNative = null;
// 定义默认的 provider 方法
const defaultProvider = {
llm: () => [] as Item[],
knowledge: () => [] as Item[],
internal: () => [] as Item[],
};
onMounted(() => {
if (divRef.value) {
// 合并默认 provider 和传入的 props.provider
const mergedProvider = {
...defaultProvider,
...props.provider,
};
tinyflow = new TinyflowNative({
element: divRef.value as Element,
data: props.data || {},
provider: mergedProvider,
});
}
});
onUnmounted(() => {
if (tinyflow) {
tinyflow.destroy();
tinyflow = null;
}
});
const getData = () => {
if (tinyflow) {
return tinyflow.getData();
}
console.warn('Tinyflow instance is not initialized');
return null;
};
defineExpose({
getData,
});
</script>
<template>
<div
ref="divRef"
class="tinyflow"
:class="[className]"
:style="style"
style="height: 100%"
></div>
</template>

View File

@@ -1,2 +0,0 @@
export { default as Tinyflow } from './Tinyflow.vue';
export * from './ui/typing';

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,68 +0,0 @@
export interface Item {
children?: Item[];
label: string;
value: number | string;
}
export interface Position {
x: number;
y: number;
}
export interface Viewport {
x: number;
y: number;
zoom: number;
}
export interface Node {
data?: Record<string, any>;
draggable?: boolean;
height?: number;
id: string;
position: Position;
selected?: boolean;
type?: string;
width?: number;
}
export interface Edge {
animated?: boolean;
id: string;
label?: string;
source: string;
target: string;
type?: string;
}
export type TinyflowData = Partial<{
edges: Edge[];
nodes: Node[];
viewport: Viewport;
}>;
export interface TinyflowOptions {
data?: TinyflowData;
element: Element | string;
provider?: {
internal?: () => Item[] | Promise<Item[]>;
knowledge?: () => Item[] | Promise<Item[]>;
llm?: () => Item[] | Promise<Item[]>;
};
}
export declare class Tinyflow {
private _init;
private _setOptions;
private options;
private rootEl;
private svelteFlowInstance;
constructor(options: TinyflowOptions);
destroy(): void;
getData(): {
edges: Edge[];
nodes: Node[];
viewport: Viewport;
};
getOptions(): TinyflowOptions;
setData(data: TinyflowData): void;
}

View File

@@ -29,8 +29,8 @@ const Description = defineComponent({
},
setup(props: DescriptionsOptions) {
// TODO @puhui999:每个 field 的 slot 的考虑
// TODO @puhui999from 5.0extra: () => getSlot(slots, 'extra')
// TODO @xingyu:每个 field 的 slot 的考虑
// TODO @xingyufrom 5.0extra: () => getSlot(slots, 'extra')
/** 过滤掉不需要展示的 */
const shouldShowItem = (item: DescriptionItemSchema) => {
if (item.hidden === undefined) return true;
@@ -75,6 +75,6 @@ const Description = defineComponent({
},
});
// TODO @puhui999from 5.0emits: ['register'] 事件
// TODO @xingyufrom 5.0emits: ['register'] 事件
export default Description;
</script>

View File

@@ -2,9 +2,9 @@ import type { DescriptionsProps } from 'ant-design-vue';
import type { CSSProperties, VNode } from 'vue';
// TODO @puhui999【content】这个纠结下1vben2.0 是 renderhttps://doc.vvbin.cn/components/desc.html#usage 2
// TODO @puhui999vben2.0 还有 sapn【done】、labelMinWidth、contentMinWidth
// TODO @puhui999【hidden】这个纠结下1vben2.0 是 show
// TODO @xingyu【content】这个纠结下1vben2.0 是 renderhttps://doc.vvbin.cn/components/desc.html#usage 2
// TODO @xingyuvben2.0 还有 sapn【done】、labelMinWidth、contentMinWidth
// TODO @xingyu【hidden】这个纠结下1vben2.0 是 show
export interface DescriptionItemSchema {
label: string | VNode; // 内容的描述
field?: string; // 对应 data 中的字段名
@@ -15,11 +15,11 @@ export interface DescriptionItemSchema {
hidden?: ((data: any) => boolean) | boolean; // 是否显示
}
// TODO @puhui999vben2.0 还有 title【done】、bordered【done】d、useCollapse、collapseOptions
// TODO @puhui999from 5.0bordered 默认为 true
// TODO @puhui999from 5.0column 默认为 lg: 3, md: 3, sm: 2, xl: 3, xs: 1, xxl: 4
// TODO @puhui999from 5.0size 默认为 small有 'default', 'middle', 'small', undefined
// TODO @puhui999from 5.0useCollapse 默认为 true
// TODO @xingyuvben2.0 还有 title【done】、bordered【done】d、useCollapse、collapseOptions
// TODO @xingyufrom 5.0bordered 默认为 true
// TODO @xingyufrom 5.0column 默认为 lg: 3, md: 3, sm: 2, xl: 3, xs: 1, xxl: 4
// TODO @xingyufrom 5.0size 默认为 small有 'default', 'middle', 'small', undefined
// TODO @xingyufrom 5.0useCollapse 默认为 true
export interface DescriptionsOptions {
data?: Record<string, any>; // 数据
schema?: DescriptionItemSchema[]; // 描述项配置

View File

@@ -2,7 +2,7 @@ import type { DescriptionsOptions } from './typing';
import { defineComponent, h, isReactive, reactive, watch } from 'vue';
import { Description } from './index';
import Description from './description.vue';
/** 描述列表 api 定义 */
class DescriptionApi {
@@ -16,7 +16,7 @@ class DescriptionApi {
return this.state as DescriptionsOptions;
}
// TODO @puhui999【setState】纠结下1vben2.0 是 data https://doc.vvbin.cn/components/desc.html#usage
// TODO @xingyu【setState】纠结下1vben2.0 是 data https://doc.vvbin.cn/components/desc.html#usage
setState(newState: Partial<DescriptionsOptions>) {
this.state = { ...this.state, ...newState };
}
@@ -27,7 +27,7 @@ export type ExtendedDescriptionApi = DescriptionApi;
export function useDescription(options: DescriptionsOptions) {
const IS_REACTIVE = isReactive(options);
const api = new DescriptionApi(options);
// 扩展API
// 扩展 API
const extendedApi: ExtendedDescriptionApi = api as never;
const Desc = defineComponent({
name: 'UseDescription',

View File

@@ -1,12 +1,11 @@
<script setup lang="ts">
import { computed } from 'vue';
import { getDictObj } from '@vben/hooks';
import { isValidColor, TinyColor } from '@vben/utils';
import { Tag } from 'ant-design-vue';
import { getDictObj } from '#/utils';
interface DictTagProps {
/**
* 字典类型

View File

@@ -4,6 +4,8 @@ import type { DictSelectProps } from '../typing';
import { computed, useAttrs } from 'vue';
import { getDictOptions } from '@vben/hooks';
import {
Checkbox,
CheckboxGroup,
@@ -13,8 +15,6 @@ import {
SelectOption,
} from 'ant-design-vue';
import { getDictOptions } from '#/utils';
defineOptions({ name: 'DictSelect' });
const props = withDefaults(defineProps<DictSelectProps>(), {

View File

@@ -1,12 +1,12 @@
<script setup lang="ts">
import type { OperateLogProps } from './typing';
import { DICT_TYPE } from '@vben/constants';
import { getDictLabel, getDictObj } from '@vben/hooks';
import { formatDateTime } from '@vben/utils';
import { Tag, Timeline } from 'ant-design-vue';
import { DICT_TYPE, getDictLabel, getDictObj } from '#/utils';
defineOptions({ name: 'OperateLogV2' });
withDefaults(defineProps<OperateLogProps>(), {

View File

@@ -1,2 +1,3 @@
// TODO @xingyu【待讨论】是不是把 user select 放到 user 目录的 components 下dept select 放到 dept 目录的 components 下
export { default as DeptSelectModal } from './dept-select-modal.vue';
export { default as UserSelectModal } from './user-select-modal.vue';

View File

@@ -6,6 +6,7 @@ import type { IOParameter, SimpleFlowNode } from '../../consts';
import { computed, onMounted, reactive, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import {
@@ -28,7 +29,6 @@ import {
import { getFormDetail } from '#/api/bpm/form';
import { getModelList } from '#/api/bpm/model';
import { BpmNodeTypeEnum } from '#/utils';
import {
CHILD_PROCESS_MULTI_INSTANCE_SOURCE_TYPE,

View File

@@ -9,6 +9,7 @@ import type { CopyTaskFormType } from '../../helpers';
import { computed, onMounted, reactive, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { BpmModelFormType, BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import {
@@ -27,8 +28,6 @@ import {
TreeSelect,
} from 'ant-design-vue';
import { BpmModelFormType, BpmNodeTypeEnum } from '#/utils';
import {
CANDIDATE_STRATEGY,
CandidateStrategy,

View File

@@ -6,6 +6,7 @@ import type { SimpleFlowNode } from '../../consts';
import { reactive, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import {
@@ -22,8 +23,6 @@ import {
SelectOption,
} from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import {
DELAY_TYPE,
DelayTypeEnum,

View File

@@ -5,6 +5,7 @@ import type { Ref } from 'vue';
import { computed, inject, reactive, ref } from 'vue';
import { BpmModelFormType } from '@vben/constants';
import { IconifyIcon, Plus, Trash2 } from '@vben/icons';
import { cloneDeep } from '@vben/utils';
@@ -25,8 +26,6 @@ import {
Tooltip,
} from 'ant-design-vue';
import { BpmModelFormType } from '#/utils';
import {
COMPARISON_OPERATORS,
CONDITION_CONFIG_TYPES,

View File

@@ -6,6 +6,7 @@ import type { RouterSetting, SimpleFlowNode } from '../../consts';
import { inject, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import {
@@ -21,8 +22,6 @@ import {
SelectOption,
} from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import { ConditionType } from '../../consts';
import { useNodeName, useWatchNode } from '../../helpers';
import Condition from './modules/condition.vue';

View File

@@ -9,6 +9,7 @@ import type { SystemUserApi } from '#/api/system/user';
import { inject, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { BpmModelFormType, BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import {
@@ -23,8 +24,6 @@ import {
TypographyText,
} from 'ant-design-vue';
import { BpmModelFormType, BpmNodeTypeEnum } from '#/utils';
import { FieldPermissionType, START_USER_BUTTON_SETTING } from '../../consts';
import {
useFormFieldsPermission,

View File

@@ -11,6 +11,7 @@ import type {
import { computed, getCurrentInstance, onMounted, reactive, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { cloneDeep } from '@vben/utils';
@@ -29,8 +30,6 @@ import {
Tag,
} from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import {
DEFAULT_CONDITION_GROUP_VALUE,
TRIGGER_TYPES,

View File

@@ -9,6 +9,11 @@ import type { UserTaskFormType } from '../../helpers';
import { computed, nextTick, onMounted, reactive, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import {
BpmModelFormType,
BpmNodeTypeEnum,
ProcessVariableEnum,
} from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { cloneDeep } from '@vben/utils';
@@ -34,12 +39,6 @@ import {
TypographyText,
} from 'ant-design-vue';
import {
BpmModelFormType,
BpmNodeTypeEnum,
ProcessVariableEnum,
} from '#/utils';
import {
APPROVE_METHODS,
APPROVE_TYPE,

View File

@@ -3,12 +3,11 @@ import type { SimpleFlowNode } from '../../consts';
import { inject, ref } from 'vue';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { Input } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import { NODE_DEFAULT_TEXT } from '../../consts';
import { useNodeName2, useTaskStatusClass, useWatchNode } from '../../helpers';
import ChildProcessNodeConfig from '../nodes-config/child-process-node-config.vue';

View File

@@ -3,12 +3,11 @@ import type { SimpleFlowNode } from '../../consts';
import { inject, ref } from 'vue';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { Input } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import { NODE_DEFAULT_TEXT } from '../../consts';
import { useNodeName2, useTaskStatusClass, useWatchNode } from '../../helpers';
import CopyTaskNodeConfig from '../nodes-config/copy-task-node-config.vue';

View File

@@ -3,12 +3,11 @@ import type { SimpleFlowNode } from '../../consts';
import { inject, ref } from 'vue';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { Input } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import { NODE_DEFAULT_TEXT } from '../../consts';
import { useNodeName2, useTaskStatusClass, useWatchNode } from '../../helpers';
import DelayTimerNodeConfig from '../nodes-config/delay-timer-node-config.vue';

View File

@@ -3,13 +3,12 @@ import type { SimpleFlowNode } from '../../consts';
import { getCurrentInstance, inject, nextTick, ref, watch } from 'vue';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { cloneDeep, buildShortUUID as generateUUID } from '@vben/utils';
import { Button, Input } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import {
ConditionType,
DEFAULT_CONDITION_GROUP_VALUE,

View File

@@ -3,13 +3,12 @@ import type { SimpleFlowNode } from '../../consts';
import { getCurrentInstance, inject, nextTick, ref, watch } from 'vue';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { cloneDeep, buildShortUUID as generateUUID } from '@vben/utils';
import { Button, Input } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import {
ConditionType,
DEFAULT_CONDITION_GROUP_VALUE,

View File

@@ -1,6 +1,6 @@
import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';
import { DICT_TYPE } from '#/utils';
import { DICT_TYPE } from '@vben/constants';
/** 流程实例列表字段 */
export function useGridColumns(): VxeTableGridOptions['columns'] {

View File

@@ -1,6 +1,6 @@
import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';
import { DICT_TYPE } from '#/utils';
import { DICT_TYPE } from '@vben/constants';
/** 审批记录列表字段 */
export function useGridColumns(): VxeTableGridOptions['columns'] {

View File

@@ -3,13 +3,12 @@ import type { SimpleFlowNode } from '../../consts';
import { inject, ref } from 'vue';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { cloneDeep, buildShortUUID as generateUUID } from '@vben/utils';
import { message, Popover } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import {
ApproveMethodType,
AssignEmptyHandlerType,

View File

@@ -3,13 +3,12 @@ import type { SimpleFlowNode } from '../../consts';
import { inject, nextTick, ref, watch } from 'vue';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { buildShortUUID as generateUUID } from '@vben/utils';
import { Button, Input } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import { NODE_DEFAULT_TEXT } from '../../consts';
import { useTaskStatusClass } from '../../helpers';
import ProcessNodeTree from '../process-node-tree.vue';

View File

@@ -3,12 +3,11 @@ import type { SimpleFlowNode } from '../../consts';
import { inject, ref } from 'vue';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { Input } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import { NODE_DEFAULT_TEXT } from '../../consts';
import { useNodeName2, useTaskStatusClass, useWatchNode } from '../../helpers';
import RouterNodeConfig from '../nodes-config/router-node-config.vue';

View File

@@ -7,12 +7,11 @@ import type { SimpleFlowNode } from '../../consts';
import { inject, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { Input } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import { NODE_DEFAULT_TEXT } from '../../consts';
import { useNodeName2, useTaskStatusClass, useWatchNode } from '../../helpers';
import StartUserNodeConfig from '../nodes-config/start-user-node-config.vue';

View File

@@ -3,12 +3,11 @@ import type { SimpleFlowNode } from '../../consts';
import { inject, ref } from 'vue';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { Input } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import { NODE_DEFAULT_TEXT } from '../../consts';
import { useNodeName2, useTaskStatusClass, useWatchNode } from '../../helpers';
import TriggerNodeConfig from '../nodes-config/trigger-node-config.vue';

View File

@@ -6,12 +6,11 @@ import type { SimpleFlowNode } from '../../consts';
import { inject, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { Input } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import { NODE_DEFAULT_TEXT } from '../../consts';
import { useNodeName2, useTaskStatusClass, useWatchNode } from '../../helpers';
import UserTaskNodeConfig from '../nodes-config/user-task-node-config.vue';

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import type { SimpleFlowNode } from '../consts';
import { BpmNodeTypeEnum } from '#/utils';
import { BpmNodeTypeEnum } from '@vben/constants';
import { useWatchNode } from '../helpers';
import ChildProcessNode from './nodes/child-process-node.vue';

View File

@@ -12,6 +12,7 @@ import type { SystemUserApi } from '#/api/system/user';
import { inject, onMounted, provide, ref, watch } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { BpmModelFormType, BpmNodeTypeEnum } from '@vben/constants';
import { handleTree } from '@vben/utils';
import { Button } from 'ant-design-vue';
@@ -22,7 +23,6 @@ import { getSimpleDeptList } from '#/api/system/dept';
import { getSimplePostList } from '#/api/system/post';
import { getSimpleRoleList } from '#/api/system/role';
import { getSimpleUserList } from '#/api/system/user';
import { BpmModelFormType, BpmNodeTypeEnum } from '#/utils';
import { NODE_DEFAULT_TEXT, NodeId } from '../consts';
import SimpleProcessModel from './simple-process-model.vue';

View File

@@ -3,13 +3,12 @@ import type { SimpleFlowNode } from '../consts';
import { onMounted, provide, ref } from 'vue';
import { BpmNodeTypeEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { downloadFileFromBlob, isString } from '@vben/utils';
import { Button, ButtonGroup, Modal, Row } from 'ant-design-vue';
import { BpmNodeTypeEnum } from '#/utils';
import { NODE_DEFAULT_TEXT } from '../consts';
import { useWatchNode } from '../helpers';
import ProcessNodeTree from './process-node-tree.vue';

View File

@@ -1,4 +1,4 @@
import { BpmNodeTypeEnum, BpmTaskStatusEnum } from '#/utils';
import { BpmNodeTypeEnum, BpmTaskStatusEnum } from '@vben/constants';
interface DictDataType {
label: string;

View File

@@ -18,7 +18,7 @@ import {
BpmNodeTypeEnum,
BpmTaskStatusEnum,
ProcessVariableEnum,
} from '#/utils';
} from '@vben/constants';
import {
ApproveMethodType,

View File

@@ -1 +0,0 @@
export { default as TableToolbar } from './table-toolbar.vue';

View File

@@ -1,81 +0,0 @@
<!-- add by puhui999vxe table 工具栏二次封装提供给 vxe 原生列表使用 -->
<script setup lang="ts">
import type { VxeToolbarInstance } from '#/adapter/vxe-table';
import { ref } from 'vue';
import { useContentMaximize, useRefresh } from '@vben/hooks';
import { IconifyIcon } from '@vben/icons';
import { Button, Tooltip } from 'ant-design-vue';
import { VxeToolbar } from '#/adapter/vxe-table';
/** 列表工具栏封装 */
defineOptions({ name: 'TableToolbar' });
const props = defineProps<{
hiddenSearch: boolean;
}>();
const emits = defineEmits(['update:hiddenSearch']);
const toolbarRef = ref<VxeToolbarInstance>();
const { toggleMaximizeAndTabbarHidden, contentIsMaximize } =
useContentMaximize();
const { refresh } = useRefresh();
/** 隐藏搜索栏 */
function onHiddenSearchBar() {
emits('update:hiddenSearch', !props.hiddenSearch);
}
defineExpose({
getToolbarRef: () => toolbarRef.value,
});
</script>
<template>
<VxeToolbar ref="toolbarRef" custom>
<template #toolPrefix>
<slot></slot>
<Tooltip placement="bottom">
<template #title>
<div class="max-w-52">搜索</div>
</template>
<Button
class="ml-2 font-normal"
shape="circle"
@click="onHiddenSearchBar"
>
<IconifyIcon icon="lucide:search" :size="15" />
</Button>
</Tooltip>
<Tooltip placement="bottom">
<template #title>
<div class="max-w-52">刷新</div>
</template>
<Button class="ml-2 font-medium" shape="circle" @click="refresh">
<IconifyIcon icon="lucide:refresh-cw" :size="15" />
</Button>
</Tooltip>
<Tooltip placement="bottom">
<template #title>
<div class="max-w-52">
{{ contentIsMaximize ? '还原' : '全屏' }}
</div>
</template>
<Button
class="ml-2 font-medium"
shape="circle"
@click="toggleMaximizeAndTabbarHidden"
>
<IconifyIcon
:icon="contentIsMaximize ? 'lucide:minimize' : 'lucide:maximize'"
:size="15"
/>
</Button>
</Tooltip>
</template>
</VxeToolbar>
</template>

View File

@@ -2,8 +2,6 @@
import type { IPropTypes } from '@tinymce/tinymce-vue/lib/cjs/main/ts/components/EditorPropTypes';
import type { Editor as EditorType } from 'tinymce/tinymce';
import type { PropType } from 'vue';
import {
computed,
nextTick,
@@ -35,37 +33,26 @@ type InitOptions = IPropTypes['init'];
defineOptions({ name: 'Tinymce', inheritAttrs: false });
const props = defineProps({
options: {
type: Object as PropType<Partial<InitOptions>>,
default: () => ({}),
},
toolbar: {
type: String,
default: defaultToolbar,
},
plugins: {
type: String,
default: defaultPlugins,
},
height: {
type: [Number, String] as PropType<number | string>,
required: false,
default: 400,
},
width: {
type: [Number, String] as PropType<number | string>,
required: false,
default: 'auto',
},
showImageUpload: {
type: Boolean,
default: true,
},
const props = withDefaults(defineProps<TinymacProps>(), {
height: 400,
width: 'auto',
options: () => ({}),
plugins: defaultPlugins,
toolbar: defaultToolbar,
showImageUpload: true,
});
const emit = defineEmits(['change']);
interface TinymacProps {
options?: Partial<InitOptions>;
toolbar?: string;
plugins?: string;
height?: number | string;
width?: number | string;
showImageUpload?: boolean;
}
/** 外部使用 v-model 绑定值 */
const modelValue = defineModel('modelValue', { default: '', type: String });
@@ -151,7 +138,7 @@ const initOptions = computed((): InitOptions => {
'bold italic | quicklink h2 h3 blockquote quickimage quicktable',
toolbar_mode: 'sliding',
...options,
images_upload_handler: (blobInfo) => {
images_upload_handler: (blobInfo: any) => {
return new Promise((resolve, reject) => {
const file = blobInfo.blob() as File;
const { httpRequest } = useUpload();
@@ -165,9 +152,9 @@ const initOptions = computed((): InitOptions => {
});
});
},
setup: (editor) => {
setup: (editor: EditorType) => {
editorRef.value = editor;
editor.on('init', (e) => initSetup(e));
editor.on('init', (e: any) => initSetup(e));
},
};
});

View File

@@ -7,7 +7,6 @@ import { computed, unref } from 'vue';
import { useAppConfig } from '@vben/hooks';
import { $t } from '@vben/locales';
// import CryptoJS from 'crypto-js';
import { createFile, getFilePresignedUrl, uploadFile } from '#/api/infra/file';
import { baseRequestClient } from '#/api/request';

View File

@@ -1 +0,0 @@
export * from './use-table-toolbar';

View File

@@ -133,7 +133,7 @@ async function handleNotificationMakeAll() {
/** 清空通知 */
async function handleNotificationClear() {
handleNotificationMakeAll();
await handleNotificationMakeAll();
}
/** 标记单个已读 */

View File

@@ -3,14 +3,14 @@ import type { Router } from 'vue-router';
import { LOGIN_PATH } from '@vben/constants';
import { $t } from '@vben/locales';
import { preferences } from '@vben/preferences';
import { useAccessStore, useUserStore } from '@vben/stores';
import { useAccessStore, useDictStore, useUserStore } from '@vben/stores';
import { startProgress, stopProgress } from '@vben/utils';
import { message } from 'ant-design-vue';
import { getSimpleDictDataList } from '#/api/system/dict/data';
import { accessRoutes, coreRouteNames } from '#/router/routes';
import { useAuthStore, useDictStore } from '#/store';
import { useAuthStore } from '#/store';
import { generateAccess } from './access';

View File

@@ -1,6 +1,6 @@
import type { RouteRecordRaw } from 'vue-router';
// OA请假相关路由配置
// OA 请假相关路由配置
const routes: RouteRecordRaw[] = [
{
path: '/bpm/oa',

View File

@@ -1,76 +1,76 @@
// import type { RouteRecordRaw } from 'vue-router';
import type { RouteRecordRaw } from 'vue-router';
// const routes: RouteRecordRaw[] = [
// {
// path: '/mall/product',
// name: 'ProductCenter',
// meta: {
// title: '商品中心',
// icon: 'lucide:shopping-bag',
// keepAlive: true,
// hideInMenu: true,
// },
// children: [
// {
// path: 'spu/add',
// name: 'ProductSpuAdd',
// meta: {
// title: '商品添加',
// activeMenu: '/mall/product/spu',
// },
// component: () => import('#/views/mall/product/spu/form/index.vue'),
// },
// {
// path: String.raw`spu/edit/:id(\d+)`,
// name: 'ProductSpuEdit',
// meta: {
// title: '商品编辑',
// activeMenu: '/mall/product/spu',
// },
// component: () => import('#/views/mall/product/spu/form/index.vue'),
// },
// {
// path: String.raw`spu/detail/:id(\d+)`,
// name: 'ProductSpuDetail',
// meta: {
// title: '商品详情',
// activeMenu: '/crm/business',
// },
// component: () => import('#/views/mall/product/spu/form/index.vue'),
// },
// ],
// },
// {
// path: '/mall/trade',
// name: 'TradeCenter',
// meta: {
// title: '交易中心',
// icon: 'lucide:shopping-cart',
// keepAlive: true,
// hideInMenu: true,
// },
// children: [
// {
// path: String.raw`order/detail/:id(\d+)`,
// name: 'TradeOrderDetail',
// meta: {
// title: '订单详情',
// activeMenu: '/mall/trade/order',
// },
// component: () => import('#/views/mall/trade/order/detail/index.vue'),
// },
// {
// path: String.raw`after-sale/detail/:id(\d+)`,
// name: 'TradeAfterSaleDetail',
// meta: {
// title: '退款详情',
// activeMenu: '/mall/trade/after-sale',
// },
// component: () =>
// import('#/views/mall/trade/afterSale/detail/index.vue'),
// },
// ],
// },
// ];
const routes: RouteRecordRaw[] = [
{
path: '/mall/product',
name: 'ProductCenter',
meta: {
title: '商品中心',
icon: 'lucide:shopping-bag',
keepAlive: true,
hideInMenu: true,
},
children: [
{
path: 'spu/add',
name: 'ProductSpuAdd',
meta: {
title: '商品添加',
activeMenu: '/mall/product/spu',
},
component: () => import('#/views/mall/product/spu/modules/form.vue'),
},
{
path: String.raw`spu/edit/:id(\d+)`,
name: 'ProductSpuEdit',
meta: {
title: '商品编辑',
activeMenu: '/mall/product/spu',
},
component: () => import('#/views/mall/product/spu/modules/form.vue'),
},
{
path: String.raw`spu/detail/:id(\d+)`,
name: 'ProductSpuDetail',
meta: {
title: '商品详情',
activeMenu: '/crm/business',
},
component: () => import('#/views/mall/product/spu/modules/detail.vue'),
},
],
},
{
path: '/mall/trade',
name: 'TradeCenter',
meta: {
title: '交易中心',
icon: 'lucide:shopping-cart',
keepAlive: true,
hideInMenu: true,
},
children: [
{
path: String.raw`order/detail/:id(\d+)`,
name: 'TradeOrderDetail',
meta: {
title: '订单详情',
activeMenu: '/mall/trade/order',
},
component: () => import('#/views/mall/trade/order/modules/detail.vue'),
},
{
path: String.raw`after-sale/detail/:id(\d+)`,
name: 'TradeAfterSaleDetail',
meta: {
title: '退款详情',
activeMenu: '/mall/trade/after-sale',
},
component: () =>
import('#/views/mall/trade/afterSale/modules/detail.vue'),
},
],
},
];
// export default routes;
export default routes;

View File

@@ -1,2 +1 @@
export * from './auth';
export * from './dict';

View File

@@ -1,327 +0,0 @@
// TODO @芋艿:后续再优化
// TODO @芋艿:可以共享么?
import type { DictItem } from '#/store';
import { isObject } from '@vben/utils';
import { useDictStore } from '#/store';
// TODO @dhb52top-level 调用 导致:"getActivePinia()" was called but there was no active Pinia
// 先临时移入到方法中
// const dictStore = useDictStore();
/** AntD 组件的颜色类型 */
type ColorType = 'error' | 'info' | 'success' | 'warning';
/** 字典值类型 */
type DictValueType = 'boolean' | 'number' | 'string';
/** 基础字典数据类型 */
export interface DictDataType {
dictType?: string;
label: string;
value: boolean | number | string;
colorType?: string;
cssClass?: string;
}
/** 数字类型字典数据 */
export interface NumberDictDataType extends DictDataType {
value: number;
}
/** 字符串类型字典数据 */
export interface StringDictDataType extends DictDataType {
value: string;
}
/** 布尔类型字典数据 */
export interface BooleanDictDataType extends DictDataType {
value: boolean;
}
/** 字典缓存管理器 */
class DictCacheManager {
private cache = new Map<string, DictDataType[]>();
private maxCacheSize = 100; // 最大缓存数量
/** 清空缓存 */
clear(): void {
this.cache.clear();
}
/** 删除指定字典类型的缓存 */
delete(dictType: string): void {
const keysToDelete = [];
for (const key of this.cache.keys()) {
if (key.startsWith(`${dictType}:`)) {
keysToDelete.push(key);
}
}
keysToDelete.forEach((key) => this.cache.delete(key));
}
/** 获取缓存数据 */
get(dictType: string, valueType: DictValueType): DictDataType[] | undefined {
return this.cache.get(this.getCacheKey(dictType, valueType));
}
/** 设置缓存数据 */
set(dictType: string, valueType: DictValueType, data: DictDataType[]): void {
const key = this.getCacheKey(dictType, valueType);
// 如果缓存数量超过限制,删除最早的缓存
if (this.cache.size >= this.maxCacheSize) {
const firstKey = this.cache.keys().next().value;
if (firstKey) {
this.cache.delete(firstKey);
}
}
this.cache.set(key, data);
}
/** 获取缓存键 */
private getCacheKey(dictType: string, valueType: DictValueType): string {
return `${dictType}:${valueType}`;
}
}
/** 字典缓存实例 */
const dictCache = new DictCacheManager();
/** 值转换器映射 */
const valueConverters: Record<
DictValueType,
(value: any) => boolean | number | string
> = {
boolean: (value: any) => `${value}` === 'true',
number: (value: any) => Number.parseInt(`${value}`, 10),
string: (value: any) => `${value}`,
};
/**
* 获取字典标签
* @param dictType 字典类型
* @param value 字典值
* @returns 字典标签
*/
function getDictLabel(dictType: string, value: any): string {
const dictStore = useDictStore();
const dictObj = dictStore.getDictData(dictType, value);
return isObject(dictObj) ? dictObj.label : '';
}
/**
* 获取字典对象
* @param dictType 字典类型
* @param value 字典值
* @returns 字典对象
*/
function getDictObj(dictType: string, value: any): DictItem | null {
const dictStore = useDictStore();
const dictObj = dictStore.getDictData(dictType, value);
return isObject(dictObj) ? dictObj : null;
}
/**
* 获取字典数组 - 优化版本,支持缓存和泛型
* @param dictType 字典类型
* @param valueType 字典值类型,默认 string 类型
* @returns 字典数组
*/
function getDictOptions<T extends DictValueType = 'string'>(
dictType: string,
valueType: T = 'string' as T,
): T extends 'number'
? NumberDictDataType[]
: T extends 'boolean'
? BooleanDictDataType[]
: StringDictDataType[] {
// 检查缓存
const cachedData = dictCache.get(dictType, valueType);
if (cachedData) {
return cachedData as any;
}
const dictStore = useDictStore();
const dictOpts = dictStore.getDictOptions(dictType);
if (dictOpts.length === 0) {
return [] as any;
}
const converter = valueConverters[valueType];
const dictOptions: DictDataType[] = dictOpts.map((d: DictItem) => ({
value: converter(d.value),
label: d.label,
colorType: d.colorType,
cssClass: d.cssClass,
}));
// 缓存结果
dictCache.set(dictType, valueType, dictOptions);
return dictOptions as any;
}
/**
* 清空字典缓存
*/
export const clearDictCache = (): void => {
dictCache.clear();
};
/**
* 删除指定字典类型的缓存
* @param dictType 字典类型
*/
export const deleteDictCache = (dictType: string): void => {
dictCache.delete(dictType);
};
/** 字典类型枚举 - 按模块分组和排序 */
enum DICT_TYPE {
AI_GENERATE_MODE = 'ai_generate_mode', // AI 生成模式
AI_IMAGE_STATUS = 'ai_image_status', // AI 图片状态
AI_MODEL_TYPE = 'ai_model_type', // AI 模型类型
AI_MUSIC_STATUS = 'ai_music_status', // AI 音乐状态
// ========== AI - 人工智能模块 ==========
AI_PLATFORM = 'ai_platform', // AI 平台
AI_WRITE_FORMAT = 'ai_write_format', // AI 写作格式
AI_WRITE_LANGUAGE = 'ai_write_language', // AI 写作语言
AI_WRITE_LENGTH = 'ai_write_length', // AI 写作长度
AI_WRITE_TONE = 'ai_write_tone', // AI 写作语气
AI_WRITE_TYPE = 'ai_write_type', // AI 写作类型
BPM_MODEL_FORM_TYPE = 'bpm_model_form_type',
// ========== BPM 模块 ==========
BPM_MODEL_TYPE = 'bpm_model_type',
BPM_OA_LEAVE_TYPE = 'bpm_oa_leave_type',
BPM_PROCESS_INSTANCE_STATUS = 'bpm_process_instance_status',
BPM_PROCESS_LISTENER_TYPE = 'bpm_process_listener_type',
BPM_PROCESS_LISTENER_VALUE_TYPE = 'bpm_process_listener_value_type',
BPM_TASK_CANDIDATE_STRATEGY = 'bpm_task_candidate_strategy',
BPM_TASK_STATUS = 'bpm_task_status',
BROKERAGE_BANK_NAME = 'brokerage_bank_name', // 佣金提现银行
BROKERAGE_BIND_MODE = 'brokerage_bind_mode', // 分销关系绑定模式
BROKERAGE_ENABLED_CONDITION = 'brokerage_enabled_condition', // 分佣模式
BROKERAGE_RECORD_BIZ_TYPE = 'brokerage_record_biz_type', // 佣金业务类型
BROKERAGE_RECORD_STATUS = 'brokerage_record_status', // 佣金状态
BROKERAGE_WITHDRAW_STATUS = 'brokerage_withdraw_status', // 佣金提现状态
BROKERAGE_WITHDRAW_TYPE = 'brokerage_withdraw_type', // 佣金提现类型
COMMON_STATUS = 'common_status',
// ========== CRM - 客户管理模块 ==========
CRM_AUDIT_STATUS = 'crm_audit_status', // CRM 审批状态
CRM_BIZ_TYPE = 'crm_biz_type', // CRM 业务类型
CRM_BUSINESS_END_STATUS_TYPE = 'crm_business_end_status_type', // CRM 商机结束状态类型
CRM_CUSTOMER_INDUSTRY = 'crm_customer_industry', // CRM 客户所属行业
CRM_CUSTOMER_LEVEL = 'crm_customer_level', // CRM 客户级别
CRM_CUSTOMER_SOURCE = 'crm_customer_source', // CRM 客户来源
CRM_FOLLOW_UP_TYPE = 'crm_follow_up_type', // CRM 跟进方式
CRM_PERMISSION_LEVEL = 'crm_permission_level', // CRM 数据权限的级别
CRM_PRODUCT_STATUS = 'crm_product_status', // CRM 商品状态
CRM_PRODUCT_UNIT = 'crm_product_unit', // CRM 产品单位
CRM_RECEIVABLE_RETURN_TYPE = 'crm_receivable_return_type', // CRM 回款的还款方式
DATE_INTERVAL = 'date_interval', // 数据间隔
// ========== ERP - 企业资源计划模块 ==========
ERP_AUDIT_STATUS = 'erp_audit_status', // ERP 审批状态
ERP_STOCK_RECORD_BIZ_TYPE = 'erp_stock_record_biz_type', // 库存明细的业务类型
// ========== MALL - 交易模块 ==========
EXPRESS_CHARGE_MODE = 'trade_delivery_express_charge_mode', // 快递的计费方式
INFRA_API_ERROR_LOG_PROCESS_STATUS = 'infra_api_error_log_process_status',
// ========== INFRA 模块 ==========
INFRA_BOOLEAN_STRING = 'infra_boolean_string',
INFRA_CODEGEN_FRONT_TYPE = 'infra_codegen_front_type',
INFRA_CODEGEN_SCENE = 'infra_codegen_scene',
INFRA_CODEGEN_TEMPLATE_TYPE = 'infra_codegen_template_type',
INFRA_CONFIG_TYPE = 'infra_config_type',
INFRA_FILE_STORAGE = 'infra_file_storage',
INFRA_JOB_LOG_STATUS = 'infra_job_log_status',
INFRA_JOB_STATUS = 'infra_job_status',
INFRA_OPERATE_TYPE = 'infra_operate_type',
IOT_DATA_FORMAT = 'iot_data_format', // IOT 数据格式
IOT_DATA_TYPE = 'iot_data_type', // IOT 数据类型
IOT_DEVICE_STATUS = 'iot_device_status', // IOT 设备状态
// ========== IOT - 物联网模块 ==========
IOT_NET_TYPE = 'iot_net_type', // IOT 联网方式
IOT_PRODUCT_DEVICE_TYPE = 'iot_product_device_type', // IOT 产品设备类型
IOT_PRODUCT_FUNCTION_TYPE = 'iot_product_function_type', // IOT 产品功能类型
IOT_PRODUCT_STATUS = 'iot_product_status', // IOT 产品状态
IOT_PROTOCOL_TYPE = 'iot_protocol_type', // IOT 接入网关协议
IOT_RW_TYPE = 'iot_rw_type', // IOT 读写类型
IOT_UNIT_TYPE = 'iot_unit_type', // IOT 单位类型
IOT_VALIDATE_TYPE = 'iot_validate_type', // IOT 数据校验级别
MEMBER_EXPERIENCE_BIZ_TYPE = 'member_experience_biz_type', // 会员经验业务类型
// ========== Member 会员模块 ==========
MEMBER_POINT_BIZ_TYPE = 'member_point_biz_type', // 积分的业务类型
// ========== MP 模块 ==========
MP_AUTO_REPLY_REQUEST_MATCH = 'mp_auto_reply_request_match', // 自动回复请求匹配类型
MP_MESSAGE_TYPE = 'mp_message_type', // 消息类型
// ========== PAY 模块 ==========
PAY_CHANNEL_CODE = 'pay_channel_code', // 支付渠道编码类型
PAY_NOTIFY_STATUS = 'pay_notify_status', // 商户支付回调状态
PAY_NOTIFY_TYPE = 'pay_notify_type', // 商户支付回调状态
PAY_ORDER_STATUS = 'pay_order_status', // 商户支付订单状态
PAY_REFUND_STATUS = 'pay_refund_status', // 退款订单状态
PAY_TRANSFER_STATUS = 'pay_transfer_status', // 转账订单状态
PAY_TRANSFER_TYPE = 'pay_transfer_type', // 转账订单状态
// ========== MALL - 商品模块 ==========
PRODUCT_SPU_STATUS = 'product_spu_status', // 商品状态
PROMOTION_BANNER_POSITION = 'promotion_banner_position', // banner 定位
PROMOTION_BARGAIN_RECORD_STATUS = 'promotion_bargain_record_status', // 砍价记录的状态
PROMOTION_COMBINATION_RECORD_STATUS = 'promotion_combination_record_status', // 拼团记录的状态
PROMOTION_CONDITION_TYPE = 'promotion_condition_type', // 营销的条件类型枚举
PROMOTION_COUPON_STATUS = 'promotion_coupon_status', // 优惠劵的状态
PROMOTION_COUPON_TAKE_TYPE = 'promotion_coupon_take_type', // 优惠劵的领取方式
PROMOTION_COUPON_TEMPLATE_VALIDITY_TYPE = 'promotion_coupon_template_validity_type', // 优惠劵模板的有限期类型
// ========== MALL - 营销模块 ==========
PROMOTION_DISCOUNT_TYPE = 'promotion_discount_type', // 优惠类型
PROMOTION_PRODUCT_SCOPE = 'promotion_product_scope', // 营销的商品范围
SYSTEM_DATA_SCOPE = 'system_data_scope',
SYSTEM_LOGIN_RESULT = 'system_login_result',
SYSTEM_LOGIN_TYPE = 'system_login_type',
SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status',
SYSTEM_MENU_TYPE = 'system_menu_type',
SYSTEM_NOTICE_TYPE = 'system_notice_type',
SYSTEM_NOTIFY_TEMPLATE_TYPE = 'system_notify_template_type',
SYSTEM_OAUTH2_GRANT_TYPE = 'system_oauth2_grant_type',
SYSTEM_ROLE_TYPE = 'system_role_type',
SYSTEM_SMS_CHANNEL_CODE = 'system_sms_channel_code',
SYSTEM_SMS_RECEIVE_STATUS = 'system_sms_receive_status',
SYSTEM_SMS_SEND_STATUS = 'system_sms_send_status',
SYSTEM_SMS_TEMPLATE_TYPE = 'system_sms_template_type',
SYSTEM_SOCIAL_TYPE = 'system_social_type',
// ========== SYSTEM 模块 ==========
SYSTEM_USER_SEX = 'system_user_sex',
TERMINAL = 'terminal', // 终端
TRADE_AFTER_SALE_STATUS = 'trade_after_sale_status', // 售后 - 状态
TRADE_AFTER_SALE_TYPE = 'trade_after_sale_type', // 售后 - 类型
TRADE_AFTER_SALE_WAY = 'trade_after_sale_way', // 售后 - 方式
TRADE_DELIVERY_TYPE = 'trade_delivery_type', // 配送方式
TRADE_ORDER_ITEM_AFTER_SALE_STATUS = 'trade_order_item_after_sale_status', // 订单项 - 售后状态
TRADE_ORDER_STATUS = 'trade_order_status', // 订单 - 状态
TRADE_ORDER_TYPE = 'trade_order_type', // 订单 - 类型
USER_TYPE = 'user_type',
}
export {
type ColorType,
DICT_TYPE,
type DictValueType,
getDictLabel,
getDictObj,
getDictOptions,
};

View File

@@ -1,5 +1,3 @@
export * from './constants';
export * from './dict';
export * from './formCreate';
export * from './rangePickerProps';
export * from './routerHelper';

View File

@@ -48,6 +48,7 @@ export function getRangePickerDefaultProps() {
format: 'HH:mm:ss',
},
transformDateFunc: (dates: any) => {
// TODO @xingyu貌似这个没用
if (dates && dates.length === 2) {
// 格式化为后台支持的时间格式
return [dates.createTime[0], dates.createTime[1]].join(',');

View File

@@ -5,13 +5,14 @@ import type { SystemUserProfileApi } from '#/api/system/user/profile';
import { watch } from 'vue';
import { DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks';
import { $t } from '@vben/locales';
import { message } from 'ant-design-vue';
import { useVbenForm, z } from '#/adapter/form';
import { updateUserProfile } from '#/api/system/user/profile';
import { DICT_TYPE, getDictOptions } from '#/utils';
const props = defineProps<{
profile?: SystemUserProfileApi.UserProfileResp;

View File

@@ -115,7 +115,11 @@ async function handelUpload({
所属岗位
</div>
</template>
{{ profile.posts && profile.posts.length > 0 ? profile.posts.map(post => post.name).join(',') : '-' }}
{{
profile.posts && profile.posts.length > 0
? profile.posts.map((post) => post.name).join(',')
: '-'
}}
</DescriptionsItem>
<DescriptionsItem>
<template #label>

View File

@@ -6,6 +6,8 @@ import { computed, onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import { confirm } from '@vben/common-ui';
import { DICT_TYPE, SystemUserSocialTypeEnum } from '@vben/constants';
import { getDictLabel } from '@vben/hooks';
import { getUrlValue } from '@vben/utils';
import { Button, Card, Image, message } from 'ant-design-vue';
@@ -18,7 +20,6 @@ import {
socialUnbind,
} from '#/api/system/social/user';
import { $t } from '#/locales';
import { DICT_TYPE, getDictLabel, SystemUserSocialTypeEnum } from '#/utils';
const emit = defineEmits<{
(e: 'update:activeName', v: string): void;

View File

@@ -65,7 +65,7 @@ const [Modal, modalApi] = useVbenModal({
}
modalApi.lock();
try {
formData.value = await getChatConversationMy(data.id as number);
formData.value = await getChatConversationMy(data.id);
// 设置到 values
await formApi.setValues(formData.value);
} finally {

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