修改
@@ -33,6 +33,7 @@
|
||||
"@jeesite/core": "workspace:*",
|
||||
"@jeesite/dbm": "workspace:*",
|
||||
"@jeesite/dfm": "workspace:*",
|
||||
"@jeesite/erp": "workspace:^",
|
||||
"@jeesite/test": "workspace:*",
|
||||
"@jeesite/types": "workspace:*",
|
||||
"@jeesite/vite": "workspace:*",
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 31 KiB |
@@ -68,5 +68,10 @@ export const bizListItemImportData = (
|
||||
params,
|
||||
);
|
||||
|
||||
export const bizListItemSflow = (params?: BizListItem | any) =>
|
||||
defHttp.get<BizListItem>({ url: adminPath + '/biz/listItem/sflow', params });
|
||||
|
||||
export const bizListItemDelete = (params?: BizListItem | any) =>
|
||||
defHttp.get<BizListItem>({ url: adminPath + '/biz/listItem/delete', params });
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ export interface BizProjectInfo extends BasicModel<BizProjectInfo> {
|
||||
|
||||
export const bizProjectInfoList = (params?: BizProjectInfo | any) =>
|
||||
defHttp.get<BizProjectInfo>({ url: adminPath + '/biz/projectInfo/list', params });
|
||||
|
||||
export const bizProjectInfoListAll = (params?: BizProjectInfo | any) =>
|
||||
defHttp.get<BizProjectInfo[]>({ url: adminPath + '/biz/projectInfo/listAll', params });
|
||||
|
||||
export const bizProjectInfoListData = (params?: BizProjectInfo | any) =>
|
||||
defHttp.post<Page<BizProjectInfo>>({ url: adminPath + '/biz/projectInfo/listData', params });
|
||||
|
||||
@@ -50,25 +50,15 @@
|
||||
maxlength: 512,
|
||||
},
|
||||
required: true,
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('是否删除'),
|
||||
field: 'titleDelete',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'title_delete',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('发送时间'),
|
||||
label: t('到期时间'),
|
||||
field: 'datetime',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
showTime: false,
|
||||
},
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('所属类型'),
|
||||
@@ -81,32 +71,17 @@
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('是否关闭'),
|
||||
field: 'clickClose',
|
||||
component: 'Select',
|
||||
label: t('通知人员'),
|
||||
field: 'loginUser',
|
||||
fieldLabel: 'userName',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
dictType: 'click_close',
|
||||
allowClear: true,
|
||||
selectType: 'userSelect',
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('待办状态'),
|
||||
field: 'extra',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 64,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('颜色编码'),
|
||||
field: 'color',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 32,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('描述信息'),
|
||||
label: t('内容信息'),
|
||||
field: 'description',
|
||||
component: 'InputTextArea',
|
||||
required: true,
|
||||
|
||||
@@ -18,11 +18,14 @@
|
||||
<Icon icon="i-fluent:add-12-filled" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #firstColumn="{ record }">
|
||||
<a @click="handleForm({ id: record.id })" :title="record.createTime">
|
||||
{{ record.createTime }}
|
||||
<template #slotBizKey="{ record }">
|
||||
<a @click="handleForm({ id: record.id })" :title="record.title">
|
||||
{{ record.title }}
|
||||
</a>
|
||||
</template>
|
||||
<template #slotBizAvatar="{ record }">
|
||||
<img :src="record.avatar" style="width: 20px; height: 20px; object-fit: cover; border-radius: 50%; display: inline-block; vertical-align: middle;" />
|
||||
</template>
|
||||
</BasicTable>
|
||||
<InputForm @register="registerDrawer" @success="handleSuccess" />
|
||||
<FormImport @register="registerImportModal" @success="handleSuccess" />
|
||||
@@ -92,12 +95,17 @@
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('待办状态'),
|
||||
field: 'extra',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('是否已读'),
|
||||
field: 'readFlag',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'read_flag',
|
||||
dictType: 'is_open',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
@@ -106,15 +114,10 @@
|
||||
field: 'clickClose',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'click_close',
|
||||
dictType: 'is_open',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('待办状态'),
|
||||
field: 'extra',
|
||||
component: 'Input',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -126,7 +129,6 @@
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'left',
|
||||
slot: 'firstColumn',
|
||||
},
|
||||
{
|
||||
title: t('头像图标'),
|
||||
@@ -135,6 +137,7 @@
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
slot: 'slotBizAvatar',
|
||||
},
|
||||
{
|
||||
title: t('通知标题'),
|
||||
@@ -143,6 +146,7 @@
|
||||
sorter: true,
|
||||
width: 200,
|
||||
align: 'left',
|
||||
slot: 'slotBizKey',
|
||||
},
|
||||
{
|
||||
title: t('是否删除'),
|
||||
@@ -151,10 +155,10 @@
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'title_delete',
|
||||
dictType: 'is_open',
|
||||
},
|
||||
{
|
||||
title: t('发送时间'),
|
||||
title: t('到期时间'),
|
||||
dataIndex: 'datetime',
|
||||
key: 'a.datetime',
|
||||
sorter: true,
|
||||
@@ -177,16 +181,24 @@
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'read_flag',
|
||||
dictType: 'is_open',
|
||||
},
|
||||
{
|
||||
title: t('描述信息'),
|
||||
title: t('内容信息'),
|
||||
dataIndex: 'description',
|
||||
key: 'a.description',
|
||||
sorter: true,
|
||||
width: 225,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('接收用户'),
|
||||
dataIndex: 'userName',
|
||||
key: 'a.user_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('是否关闭'),
|
||||
dataIndex: 'clickClose',
|
||||
@@ -194,7 +206,7 @@
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'click_close',
|
||||
dictType: 'is_open',
|
||||
},
|
||||
{
|
||||
title: t('待办状态'),
|
||||
@@ -241,6 +253,7 @@
|
||||
confirm: handleDelete.bind(this, record),
|
||||
},
|
||||
auth: 'biz:listItem:edit',
|
||||
ifShow: record.clickClose == false
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('项目区域'),
|
||||
label: t('区域名称'),
|
||||
field: 'areaCode',
|
||||
fieldLabel: 'provinceName',
|
||||
component: 'ListSelect',
|
||||
@@ -81,7 +81,7 @@
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('需求人员'),
|
||||
label: t('需求用户'),
|
||||
field: 'employeeId',
|
||||
fieldLabel: 'employeeName',
|
||||
component: 'ListSelect',
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('项目区域'),
|
||||
label: t('区域名称'),
|
||||
field: 'areaCode',
|
||||
fieldLabel: 'provinceName',
|
||||
component: 'ListSelect',
|
||||
@@ -107,7 +107,7 @@
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('需求人员'),
|
||||
label: t('需求用户'),
|
||||
field: 'employeeId',
|
||||
fieldLabel: 'employeeName',
|
||||
component: 'ListSelect',
|
||||
@@ -172,14 +172,46 @@
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('项目区域'),
|
||||
dataIndex: 'areaCode',
|
||||
key: 'a.area_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('需求用户'),
|
||||
dataIndex: 'employeeName',
|
||||
key: 'b.employee_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('项目编码'),
|
||||
dataIndex: 'projectCode',
|
||||
key: 'c.project_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('项目名称'),
|
||||
dataIndex: 'projectName',
|
||||
key: 'c.project_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('区域编号'),
|
||||
dataIndex: 'areaCode',
|
||||
key: 'a.area_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('项目名称'),
|
||||
dataIndex: 'provinceName',
|
||||
key: 'd.province_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('需求描述'),
|
||||
dataIndex: 'requirementDescription',
|
||||
@@ -242,6 +274,7 @@
|
||||
|
||||
const actionColumn: BasicColumn<BizProjectRequirements> = {
|
||||
width: 160,
|
||||
align: 'center',
|
||||
actions: (record: BizProjectRequirements) => [
|
||||
{
|
||||
icon: 'i-clarity:note-edit-line',
|
||||
@@ -258,6 +291,7 @@
|
||||
confirm: handleDelete.bind(this, record),
|
||||
},
|
||||
auth: 'biz:projectRequirements:edit',
|
||||
ifShow: record.requirementsStatus == 'PDC'
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { BasicColumn, BasicTableProps, FormProps } from '@jeesite/core/components/Table';
|
||||
import { bizProjectRequirementsListData } from '@jeesite/biz/api/biz/projectRequirements';
|
||||
|
||||
const { t } = useI18n('biz.projectRequirements');
|
||||
|
||||
const modalProps = {
|
||||
title: t('需求信息选择'),
|
||||
};
|
||||
|
||||
const searchForm: FormProps<BizProjectRequirements> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('记录日期起'),
|
||||
field: 'createTime_gte',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('记录日期止'),
|
||||
field: 'createTime_lte',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('需求名称'),
|
||||
field: 'requirementName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('需求编号'),
|
||||
field: 'requirementCode',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('项目区域'),
|
||||
field: 'areaCode',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('需求描述'),
|
||||
field: 'requirementDescription',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('优先级'),
|
||||
field: 'priority',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: '',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('项目ID'),
|
||||
field: 'projectId',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: '',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('用户ID'),
|
||||
field: 'employeeId',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: '',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('需求备注'),
|
||||
field: 'remark',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('状态'),
|
||||
field: 'requirementsStatus',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: '',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<BizProjectRequirements>[] = [
|
||||
{
|
||||
title: t('记录日期'),
|
||||
dataIndex: 'createTime',
|
||||
key: 'a.create_time',
|
||||
sorter: true,
|
||||
width: 230,
|
||||
align: 'left',
|
||||
slot: 'firstColumn',
|
||||
},
|
||||
{
|
||||
title: t('需求名称'),
|
||||
dataIndex: 'requirementName',
|
||||
key: 'a.requirement_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('需求编号'),
|
||||
dataIndex: 'requirementCode',
|
||||
key: 'a.requirement_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('项目区域'),
|
||||
dataIndex: 'areaCode',
|
||||
key: 'a.area_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('需求描述'),
|
||||
dataIndex: 'requirementDescription',
|
||||
key: 'a.requirement_description',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('开始时间'),
|
||||
dataIndex: 'startTime',
|
||||
key: 'a.start_time',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('结束时间'),
|
||||
dataIndex: 'endTime',
|
||||
key: 'a.end_time',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('优先级'),
|
||||
dataIndex: 'priority',
|
||||
key: 'a.priority',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: '',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
key: 'a.update_time',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('项目ID'),
|
||||
dataIndex: 'projectId',
|
||||
key: 'a.project_id',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: '',
|
||||
},
|
||||
{
|
||||
title: t('用户ID'),
|
||||
dataIndex: 'employeeId',
|
||||
key: 'a.employee_id',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: '',
|
||||
},
|
||||
{
|
||||
title: t('需求备注'),
|
||||
dataIndex: 'remark',
|
||||
key: 'a.remark',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('状态'),
|
||||
dataIndex: 'requirementsStatus',
|
||||
key: 'a.requirements_status',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: '',
|
||||
},
|
||||
];
|
||||
|
||||
const tableProps: BasicTableProps = {
|
||||
api: bizProjectRequirementsListData,
|
||||
beforeFetch: (params) => {
|
||||
params['isAll'] = true;
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
formConfig: searchForm,
|
||||
rowKey: 'requirementId',
|
||||
};
|
||||
|
||||
export default {
|
||||
modalProps,
|
||||
tableProps,
|
||||
itemCode: 'requirementId',
|
||||
itemName: 'requirementId',
|
||||
isShowCode: false,
|
||||
};
|
||||
@@ -63,7 +63,7 @@
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('图标类名'),
|
||||
label: t('图标地址'),
|
||||
field: 'iconClass',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
@@ -112,7 +112,7 @@
|
||||
field: 'isEnabled',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'is_enabled',
|
||||
dictType: 'ustatus',
|
||||
allowClear: true,
|
||||
},
|
||||
required: true,
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
<Icon icon="i-fluent:add-12-filled" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #firstColumn="{ record }">
|
||||
<a @click="handleForm({ id: record.id })" :title="record.createTime">
|
||||
{{ record.createTime }}
|
||||
<template #slotBizKey="{ record }">
|
||||
<a @click="handleForm({ id: record.id })" :title="record.systemName">
|
||||
{{ record.systemName }}
|
||||
</a>
|
||||
</template>
|
||||
</BasicTable>
|
||||
@@ -85,26 +85,26 @@
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'left',
|
||||
slot: 'firstColumn',
|
||||
},
|
||||
{
|
||||
title: t('系统名称'),
|
||||
dataIndex: 'systemName',
|
||||
key: 'a.system_name',
|
||||
sorter: true,
|
||||
width: 225,
|
||||
width: 200,
|
||||
align: 'left',
|
||||
slot: 'slotBizKey',
|
||||
},
|
||||
{
|
||||
title: t('首页地址'),
|
||||
dataIndex: 'homepageUrl',
|
||||
key: 'a.homepage_url',
|
||||
sorter: true,
|
||||
width: 200,
|
||||
width: 225,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('图标类名'),
|
||||
title: t('图标地址'),
|
||||
dataIndex: 'iconClass',
|
||||
key: 'a.icon_class',
|
||||
sorter: true,
|
||||
@@ -150,7 +150,7 @@
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
dictType: 'is_enabled',
|
||||
dictType: 'ustatus',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { BasicColumn, BasicTableProps, FormProps } from '@jeesite/core/components/Table';
|
||||
import { ErpAccount, erpAccountListData } from '@jeesite/erp/api/erp/account';
|
||||
|
||||
const { t } = useI18n('erp.account');
|
||||
|
||||
const modalProps = {
|
||||
title: t('账户信息选择'),
|
||||
};
|
||||
|
||||
const searchForm: FormProps<ErpAccount> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('账户名称'),
|
||||
field: 'accountName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('账户类型'),
|
||||
field: 'accountType',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('是否激活'),
|
||||
field: 'isActive',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'is_active',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<ErpAccount>[] = [
|
||||
{
|
||||
title: t('记录时间'),
|
||||
dataIndex: 'createTime',
|
||||
key: 'a.create_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('账户名称'),
|
||||
dataIndex: 'accountName',
|
||||
key: 'a.account_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('账户类型'),
|
||||
dataIndex: 'accountType',
|
||||
key: 'a.account_type',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'account_type'
|
||||
},
|
||||
{
|
||||
title: t('账户卡号'),
|
||||
dataIndex: 'accountCode',
|
||||
key: 'a.account_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('初始余额'),
|
||||
dataIndex: 'initialBalance',
|
||||
key: 'a.initial_balance',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
title: t('当前余额'),
|
||||
dataIndex: 'currentBalance',
|
||||
key: 'a.current_balance',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
title: t('是否激活'),
|
||||
dataIndex: 'isActive',
|
||||
key: 'a.is_active',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'is_active',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
key: 'a.update_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
|
||||
const tableProps: BasicTableProps = {
|
||||
api: erpAccountListData,
|
||||
beforeFetch: (params) => {
|
||||
params['isAll'] = true;
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
formConfig: searchForm,
|
||||
rowKey: 'accountId',
|
||||
};
|
||||
|
||||
export default {
|
||||
modalProps,
|
||||
tableProps,
|
||||
itemCode: 'accountId',
|
||||
itemName: 'accountName',
|
||||
isShowCode: true,
|
||||
};
|
||||
@@ -0,0 +1,120 @@
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { BasicColumn, BasicTableProps, FormProps } from '@jeesite/core/components/Table';
|
||||
import { ErpCategory, erpCategoryListData } from '@jeesite/erp/api/erp/category';
|
||||
|
||||
const { t } = useI18n('erp.category');
|
||||
|
||||
const modalProps = {
|
||||
title: t('分类信息选择'),
|
||||
};
|
||||
|
||||
const searchForm: FormProps<ErpCategory> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('分类名称'),
|
||||
field: 'categoryName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('分类类型'),
|
||||
field: 'categoryType',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'category_type',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('是否启用'),
|
||||
field: 'isActive',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'is_active',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<ErpCategory>[] = [
|
||||
{
|
||||
title: t('记录时间'),
|
||||
dataIndex: 'createTime',
|
||||
key: 'a.create_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('分类名称'),
|
||||
dataIndex: 'categoryName',
|
||||
key: 'a.category_name',
|
||||
sorter: true,
|
||||
width: 230,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('分类类型'),
|
||||
dataIndex: 'categoryType',
|
||||
key: 'a.category_type',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'category_type',
|
||||
},
|
||||
{
|
||||
title: t('父级分类'),
|
||||
dataIndex: 'parentId',
|
||||
key: 'a.parent_id',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'parent_type',
|
||||
},
|
||||
{
|
||||
title: t('排序序号'),
|
||||
dataIndex: 'sortOrder',
|
||||
key: 'a.sort_order',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('是否启用'),
|
||||
dataIndex: 'isActive',
|
||||
key: 'a.is_active',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'is_active',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
key: 'a.update_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
|
||||
const tableProps: BasicTableProps = {
|
||||
api: erpCategoryListData,
|
||||
beforeFetch: (params) => {
|
||||
params['isAll'] = true;
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
formConfig: searchForm,
|
||||
rowKey: 'categoryId',
|
||||
};
|
||||
|
||||
export default {
|
||||
modalProps,
|
||||
tableProps,
|
||||
itemCode: 'categoryId',
|
||||
itemName: 'categoryName',
|
||||
isShowCode: false,
|
||||
};
|
||||
@@ -0,0 +1,128 @@
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { BasicColumn, BasicTableProps, FormProps } from '@jeesite/core/components/Table';
|
||||
import { ErpTransactionFlow, erpTransactionFlowListData } from '@jeesite/erp/api/erp/transactionFlow';
|
||||
|
||||
const { t } = useI18n('erp.transactionFlow');
|
||||
|
||||
const modalProps = {
|
||||
title: t('明细信息选择'),
|
||||
};
|
||||
|
||||
const searchForm: FormProps<ErpTransactionFlow> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('交易名称'),
|
||||
field: 'flowName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('交易类型'),
|
||||
field: 'transactionType',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'transaction_type',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('是否记账'),
|
||||
field: 'isFinish',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'is_finish',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<ErpTransactionFlow>[] = [
|
||||
{
|
||||
title: t('记录时间'),
|
||||
dataIndex: 'createTime',
|
||||
key: 'a.create_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'left',
|
||||
slot: 'firstColumn',
|
||||
},
|
||||
{
|
||||
title: t('交易名称'),
|
||||
dataIndex: 'flowName',
|
||||
key: 'a.flow_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('交易类型'),
|
||||
dataIndex: 'transactionType',
|
||||
key: 'a.transaction_type',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'transaction_type',
|
||||
},
|
||||
{
|
||||
title: t('交易金额'),
|
||||
dataIndex: 'amount',
|
||||
key: 'a.amount',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
title: t('交易时间'),
|
||||
dataIndex: 'transactionTime',
|
||||
key: 'a.transaction_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('交易备注'),
|
||||
dataIndex: 'remark',
|
||||
key: 'a.remark',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('是否记账'),
|
||||
dataIndex: 'isFinish',
|
||||
key: 'a.is_finish',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'is_finish',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
key: 'a.update_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
|
||||
const tableProps: BasicTableProps = {
|
||||
api: erpTransactionFlowListData,
|
||||
beforeFetch: (params) => {
|
||||
params['isAll'] = true;
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
formConfig: searchForm,
|
||||
rowKey: 'flowId',
|
||||
};
|
||||
|
||||
export default {
|
||||
modalProps,
|
||||
tableProps,
|
||||
itemCode: 'flowId',
|
||||
itemName: 'flowName',
|
||||
isShowCode: true,
|
||||
};
|
||||
@@ -1,196 +0,0 @@
|
||||
export interface ListItem {
|
||||
id: string;
|
||||
avatar: string;
|
||||
// 通知的标题内容
|
||||
title: string;
|
||||
// 是否在标题上显示删除线
|
||||
titleDelete?: boolean;
|
||||
datetime?: string;
|
||||
type: string;
|
||||
read?: boolean;
|
||||
description: string;
|
||||
clickClose?: boolean;
|
||||
extra?: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export interface TabItem {
|
||||
key: string;
|
||||
name: string;
|
||||
count?: number;
|
||||
btnHref?: string;
|
||||
btnText?: string;
|
||||
list: ListItem[];
|
||||
unreadlist?: ListItem[];
|
||||
}
|
||||
|
||||
export const tabListData: TabItem[] = [
|
||||
{
|
||||
key: '1',
|
||||
name: '通知',
|
||||
list: [
|
||||
{
|
||||
id: '000000001',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
|
||||
title: '你收到了 10 份新周报',
|
||||
description: '',
|
||||
datetime: '2022-08-09',
|
||||
type: '1',
|
||||
},
|
||||
{
|
||||
id: '000000002',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png',
|
||||
title: '你推荐的果汁已通过第三轮面试',
|
||||
description: '',
|
||||
datetime: '2022-08-08',
|
||||
type: '1',
|
||||
},
|
||||
{
|
||||
id: '000000003',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png',
|
||||
title: '这种模板可以区分多种通知类型',
|
||||
description: '',
|
||||
datetime: '2022-08-07',
|
||||
// read: true,
|
||||
type: '1',
|
||||
},
|
||||
{
|
||||
id: '000000004',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
|
||||
title: '左侧图标用于区分不同的类型',
|
||||
description: '',
|
||||
datetime: '2022-08-07',
|
||||
type: '1',
|
||||
},
|
||||
{
|
||||
id: '000000005',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
|
||||
title:
|
||||
'标题可以设置自动显示省略号,本例中标题行数已设为1行,如果内容超过1行将自动截断并支持tooltip显示完整标题。',
|
||||
description: '',
|
||||
datetime: '2022-08-07',
|
||||
type: '1',
|
||||
},
|
||||
{
|
||||
id: '000000006',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
|
||||
title: '左侧图标用于区分不同的类型',
|
||||
description: '',
|
||||
datetime: '2022-08-07',
|
||||
type: '1',
|
||||
},
|
||||
{
|
||||
id: '000000007',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
|
||||
title: '左侧图标用于区分不同的类型',
|
||||
description: '',
|
||||
datetime: '2022-08-07',
|
||||
type: '1',
|
||||
},
|
||||
{
|
||||
id: '000000008',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
|
||||
title: '左侧图标用于区分不同的类型',
|
||||
description: '',
|
||||
datetime: '2022-08-07',
|
||||
type: '1',
|
||||
},
|
||||
{
|
||||
id: '000000009',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
|
||||
title: '左侧图标用于区分不同的类型',
|
||||
description: '',
|
||||
datetime: '2022-08-07',
|
||||
type: '1',
|
||||
},
|
||||
{
|
||||
id: '000000010',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
|
||||
title: '左侧图标用于区分不同的类型',
|
||||
description: '',
|
||||
datetime: '2022-08-07',
|
||||
type: '1',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
name: '消息',
|
||||
list: [
|
||||
{
|
||||
id: '000000006',
|
||||
avatar: 'ant-design:message-outlined',
|
||||
title: '彩虹 评论了你',
|
||||
description: '描述信息描述信息描述信息',
|
||||
datetime: '2022-08-07',
|
||||
type: '2',
|
||||
clickClose: true,
|
||||
},
|
||||
{
|
||||
id: '000000007',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
|
||||
title: '果汁 回复了你',
|
||||
description: '这种模板用于提醒谁与你发生了互动',
|
||||
datetime: '2022-08-07',
|
||||
type: '2',
|
||||
clickClose: true,
|
||||
},
|
||||
{
|
||||
id: '000000008',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
|
||||
title: '标题',
|
||||
description:
|
||||
'请将鼠标移动到此处,以便测试超长的消息在此处将如何处理。本例中设置的描述最大行数为2,超过2行的描述内容将被省略并且可以通过tooltip查看完整内容',
|
||||
datetime: '2022-08-07',
|
||||
type: '2',
|
||||
clickClose: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
name: '待办',
|
||||
list: [
|
||||
{
|
||||
id: '000000009',
|
||||
avatar: '',
|
||||
title: '任务名称',
|
||||
description: '任务需要在 2022-01-12 20:00 前启动',
|
||||
datetime: '',
|
||||
extra: '未开始',
|
||||
color: '',
|
||||
type: '3',
|
||||
},
|
||||
{
|
||||
id: '000000010',
|
||||
avatar: '',
|
||||
title: '第三方紧急代码变更',
|
||||
description: '彩虹 需在 2022-01-07 前完成代码变更任务',
|
||||
datetime: '',
|
||||
extra: '马上到期',
|
||||
color: 'red',
|
||||
type: '3',
|
||||
},
|
||||
{
|
||||
id: '000000011',
|
||||
avatar: '',
|
||||
title: '信息安全考试',
|
||||
description: '指派竹尔于 2022-01-09 前完成更新并发布',
|
||||
datetime: '',
|
||||
extra: '已耗时 8 天',
|
||||
color: 'gold',
|
||||
type: '3',
|
||||
},
|
||||
{
|
||||
id: '000000012',
|
||||
avatar: '',
|
||||
title: 'ABCD 版本发布',
|
||||
description: '指派竹尔于 2022-01-09 前完成更新并发布',
|
||||
datetime: '',
|
||||
extra: '进行中',
|
||||
color: 'blue',
|
||||
type: '3',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -13,7 +13,8 @@
|
||||
<span v-if="item.list.length !== 0">({{ item.list.length }})</span>
|
||||
</template>
|
||||
<!-- 绑定title-click事件的通知列表中标题是“可点击”的-->
|
||||
<NoticeList :list="item.list" @title-click="onNoticeClick" />
|
||||
<NoticeList :list="item.list" v-if="item.key === '3'" @title-click="onNoticeClick" />
|
||||
<NoticeList :list="item.list" v-else />
|
||||
</TabPane>
|
||||
</template>
|
||||
</Tabs>
|
||||
@@ -28,7 +29,7 @@
|
||||
import NoticeList from './NoticeList.vue';
|
||||
import { useDesign } from '@jeesite/core/hooks/web/useDesign';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { tabListDataAll, TabItem, BizListItem } from '@jeesite/biz/api/biz/listItem';
|
||||
import { tabListDataAll, bizListItemSflow, TabItem, BizListItem } from '@jeesite/biz/api/biz/listItem';
|
||||
|
||||
export default defineComponent({
|
||||
components: { Popover, BellOutlined, Tabs, TabPane: Tabs.TabPane, Badge, NoticeList },
|
||||
@@ -53,10 +54,11 @@
|
||||
}
|
||||
return count;
|
||||
});
|
||||
|
||||
function onNoticeClick(record: BizListItem) {
|
||||
createMessage.success('你点击了' + record.title);
|
||||
getDataList()
|
||||
|
||||
async function onNoticeClick(record: BizListItem) {
|
||||
const res = await bizListItemSflow(record);
|
||||
createMessage.success(res.message);
|
||||
getDataList()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -121,168 +121,6 @@ export const groupItems: GroupItem[] = [
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
},
|
||||
{
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
}, {
|
||||
title: 'Vue',
|
||||
icon: 'i-ion:logo-vue',
|
||||
color: '#3fb27f',
|
||||
desc: '现在的你决定将来的你。',
|
||||
group: '前端组',
|
||||
date: '2021-09-01',
|
||||
},
|
||||
{
|
||||
title: 'Html5',
|
||||
icon: 'i-ion:logo-html5',
|
||||
|
||||
@@ -3,19 +3,37 @@
|
||||
<template #extra>
|
||||
<a-button type="link" size="small">更多</a-button>
|
||||
</template>
|
||||
|
||||
<!-- 滚动容器 + 网格布局确保一行3个 -->
|
||||
<div class="scroll-container">
|
||||
<template v-for="item in items" :key="item">
|
||||
<CardGrid class="!w-full">
|
||||
<span class="flex">
|
||||
<Icon :icon="item.icon" :color="item.color" size="30" />
|
||||
<span class="ml-4 text-lg">{{ item.title }}</span>
|
||||
</span>
|
||||
<div class="text-secondary mt-2 h-10 flex">{{ item.desc }}</div>
|
||||
<div class="text-secondary flex justify-between">
|
||||
<span>{{ item.group }}</span>
|
||||
<span>{{ item.date }}</span>
|
||||
<template v-for="item in listData" :key="item">
|
||||
<CardGrid class="!w-full rounded-lg p-4 shadow-sm hover:shadow-md transition-shadow duration-200 border border-gray-100">
|
||||
<div class="flex items-center mb-3">
|
||||
<Icon icon="i-ion:layers-outline" color="#00bfff" size="25" />
|
||||
<span class="ml-2 text-lg font-medium text-gray-800">{{ item.projectName }}</span>
|
||||
</div>
|
||||
<div class="text-gray-600 mt-1 mb-4 h-12 flex items-center overflow-auto text-sm pr-2">
|
||||
{{ item.projectDesc }}
|
||||
</div>
|
||||
<div class="bg-blue-50 rounded-md p-3 border-b-2 border-blue-200">
|
||||
<div class="text-gray-600 flex justify-between mb-2 text-sm">
|
||||
<span class="flex items-center">
|
||||
<i class="ri-calendar-start-line mr-1 text-blue-400"></i>
|
||||
开始时间: {{ item.startDate }}
|
||||
</span>
|
||||
<span class="flex items-center">
|
||||
<i class="ri-code-line mr-1 text-blue-400"></i>
|
||||
项目编码: {{ item.projectCode }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-gray-600 flex justify-between text-sm">
|
||||
<span class="flex items-center">
|
||||
<i class="ri-calendar-end-line mr-1 text-blue-400"></i>
|
||||
结束时间: {{ item.endDate }}
|
||||
</span>
|
||||
<span class="flex items-center">
|
||||
<i class="ri-user-line mr-1 text-blue-400"></i>
|
||||
项目经理: {{ item.employeeName }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardGrid>
|
||||
</template>
|
||||
@@ -23,17 +41,34 @@
|
||||
</Card>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent, onMounted, ref } from 'vue';
|
||||
import { Card } from 'ant-design-vue';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { groupItems } from './Data';
|
||||
|
||||
import { BizProjectInfo, bizProjectInfoListAll } from '@jeesite/biz/api/biz/projectInfo';
|
||||
|
||||
export default defineComponent({
|
||||
components: { Card, CardGrid: Card.Grid, Icon },
|
||||
setup() {
|
||||
return { items: groupItems };
|
||||
},
|
||||
} as any);
|
||||
components: { Card, CardGrid: Card.Grid, Icon },
|
||||
setup() {
|
||||
const listData = ref();
|
||||
const getDataList = async () => {
|
||||
try {
|
||||
const params = { projectStatus: '2' };
|
||||
const result = await bizProjectInfoListAll(params);
|
||||
listData.value = result || [];
|
||||
} catch (error) {
|
||||
listData.value = []; // 异常时置空列表,显示空状态
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getDataList()
|
||||
});
|
||||
|
||||
return {
|
||||
listData,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -46,7 +81,7 @@
|
||||
|
||||
/* 关键:网格布局一行3个 */
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr); /* 强制一行3列 */
|
||||
grid-template-columns: repeat(2, 1fr); /* 强制一行3列 */
|
||||
gap: 16px; /* 卡片间距,可按需调整 */
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<Select
|
||||
:showSearch="false"
|
||||
:options="[
|
||||
{ label: '使用手机号码找回您的密码', value: 'mobile' },
|
||||
{ label: '使用电子邮箱找回您的密码', value: 'email' },
|
||||
{ label: '使用保密问题找回您的密码', value: 'question' },
|
||||
]"
|
||||
|
||||
@@ -20,12 +20,6 @@
|
||||
<div class="-enter-x mt-10 text-white font-medium">
|
||||
<span class="mt-4 inline-block text-3xl"></span>
|
||||
</div>
|
||||
<div class="-enter-x text-md mt-5 text-white font-normal dark:text-gray-500">
|
||||
JeeSite 是一个专业的平台,是一个让你使用放心的平台。<br />
|
||||
前端基于 Vue3、Vite、TypeScript、Ant-Design-Vue、Vben Admin,<br />
|
||||
后台基于 Spring Boot、Apache MyBatis 等,最先进、最经典的技术栈。<br />
|
||||
精致的 UI、规范的代码书写、匠心著作、封装细节、专注业务、快速开发。<br />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-full w-full flex overflow-auto py-5 lg:my-0 lg:h-auto lg:w-11/24 lg:py-0">
|
||||
@@ -35,9 +29,6 @@
|
||||
>
|
||||
<LoginForm @demo-mode="demoMode = $event" />
|
||||
<ForgetPasswordForm :demoMode="demoMode" />
|
||||
<RegisterForm :demoMode="demoMode" />
|
||||
<MobileForm :demoMode="demoMode" />
|
||||
<QrCodeForm :demoMode="demoMode" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -50,37 +41,10 @@
|
||||
import { AppLocalePicker, AppDarkModeToggle } from '@jeesite/core/components/Application';
|
||||
import LoginForm from './LoginForm.vue';
|
||||
import ForgetPasswordForm from './ForgetPasswordForm.vue';
|
||||
import RegisterForm from './RegisterForm.vue';
|
||||
import MobileForm from './MobileForm.vue';
|
||||
import QrCodeForm from './QrCodeForm.vue';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { useDesign } from '@jeesite/core/hooks/web/useDesign';
|
||||
import { useLocaleStore } from '@jeesite/core/store/modules/locale';
|
||||
|
||||
/* import { onMounted } from 'vue';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
const { createConfirm } = useMessage();
|
||||
onMounted(() => {
|
||||
if (!import.meta.env.DEV) {
|
||||
createConfirm({
|
||||
content: [
|
||||
'<div onclick="window.open(\'https://gitee.com/thinkgem/jeesite-vue\')">',
|
||||
'进入 <strong style="color: #FF0036;">JeeSite Vue</strong> 源码仓库页面,',
|
||||
'点右上角 <strong style="color: #FF0036;">Star</strong> 加星关注',
|
||||
'</div>',
|
||||
].join(''),
|
||||
width: 480,
|
||||
iconType: 'info',
|
||||
maskClosable: false,
|
||||
cancelText: '我已 Star',
|
||||
okText: '带我去 Star',
|
||||
onOk: () => {
|
||||
window.open('https://gitee.com/thinkgem/jeesite-vue');
|
||||
},
|
||||
});
|
||||
}
|
||||
}); */
|
||||
|
||||
defineProps({
|
||||
sessionTimeout: {
|
||||
type: Boolean,
|
||||
|
||||
@@ -66,40 +66,7 @@
|
||||
<Button type="primary" size="large" block @click="handleLogin" :loading="loading">
|
||||
{{ t('sys.login.loginButton') }}
|
||||
</Button>
|
||||
<!-- <Button size="large" class="mt-4 enter-x" block @click="handleRegister">
|
||||
{{ t('sys.login.registerButton') }}
|
||||
</Button> -->
|
||||
</FormItem>
|
||||
<ARow class="enter-x md:pl-3">
|
||||
<ACol :md="7" :xs="24">
|
||||
<Button block @click="setLoginState(LoginStateEnum.MOBILE)">
|
||||
{{ t('sys.login.mobileSignInFormTitle') }}
|
||||
</Button>
|
||||
</ACol>
|
||||
<ACol :md="8" :xs="24" class="xs:mx-0 !my-2 md:mx-2 !md:my-0">
|
||||
<Button block @click="setLoginState(LoginStateEnum.QR_CODE)">
|
||||
{{ t('sys.login.qrSignInFormTitle') }}
|
||||
</Button>
|
||||
</ACol>
|
||||
<ACol :md="7" :xs="24">
|
||||
<Button block @click="setLoginState(LoginStateEnum.REGISTER)">
|
||||
{{ t('sys.login.registerButton') }}
|
||||
</Button>
|
||||
</ACol>
|
||||
</ARow>
|
||||
|
||||
<Divider class="enter-x">{{ t('sys.login.otherSignIn') }}</Divider>
|
||||
|
||||
<div class="enter-x flex justify-evenly" :class="`${prefixCls}-sign-in-way`">
|
||||
<Icon icon="i-simple-icons:gitee" color="#d81e06" size="28" @click="handleOauth2" />
|
||||
<Icon icon="i-ant-design:qq-circle-filled" color="#2178e3" size="32" @click="handleOauth2" />
|
||||
<Icon icon="i-ant-design:wechat-filled" color="#2eb60d" size="32" @click="handleOauth2" />
|
||||
<Icon icon="i-ant-design:github-filled" color="#2c2c2c" size="32" @click="handleOauth2" />
|
||||
<a href="https://gitee.com/thinkgem/jeesite-client" target="_blank">
|
||||
<Icon icon="i-ant-design:windows-filled" size="32" style="vertical-align: middle" />
|
||||
<span class="pl-1" style="vertical-align: middle"> {{ t('客户端下载') }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
|
||||
22
web-vue/packages/erp/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
- 官方网站:<https://jeesite.com>
|
||||
- 使用文档:<https://jeesite.com/docs>
|
||||
- 后端代码:<https://gitee.com/thinkgem/jeesite5>
|
||||
- 前端代码:<https://gitee.com/thinkgem/jeesite-vue>
|
||||
|
||||
------
|
||||
|
||||
<div align="center">
|
||||
如果你喜欢 JeeSite,请给她一个 ⭐️ Star,您的支持将是我们前行的动力。
|
||||
</div>
|
||||
|
||||
------
|
||||
|
||||
- 问题反馈:<https://gitee.com/thinkgem/jeesite-vue/issues> [【新手必读】](https://gitee.com/thinkgem/jeesite5/issues/I18ARR)
|
||||
- 需求收集:<https://gitee.com/thinkgem/jeesite-vue/issues/new>
|
||||
- QQ 群:`127515876`、`209330483`、`223507718`、`709534275`、`730390092`、`1373527`、`183903863(外包)`
|
||||
- 微信群:添加客服微信 <http://s.jeesite.com> 邀请您进群
|
||||
- 关注微信公众号,了解最新动态:
|
||||
|
||||
<p style="padding-left:40px">
|
||||
<img alt="JeeSite微信公众号" src="https://jeesite.com/assets/images/mp.png" width="220" height="220">
|
||||
</p>
|
||||
56
web-vue/packages/erp/api/erp/account.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
*/
|
||||
import { defHttp } from '@jeesite/core/utils/http/axios';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { BasicModel, Page } from '@jeesite/core/api/model/baseModel';
|
||||
import { UploadApiResult } from '@jeesite/core/api/sys/upload';
|
||||
import { UploadFileParams } from '@jeesite/types/axios';
|
||||
import { AxiosProgressEvent } from 'axios';
|
||||
|
||||
const { ctxPath, adminPath } = useGlobSetting();
|
||||
|
||||
export interface ErpAccount extends BasicModel<ErpAccount> {
|
||||
createTime?: string; // 记录时间
|
||||
accountId?: string; // 账户标识
|
||||
accountName: string; // 账户名称
|
||||
accountType: string; // 账户类型
|
||||
accountCode: string; // 账户卡号
|
||||
initialBalance: number; // 初始余额
|
||||
currentBalance: number; // 当前余额
|
||||
isActive: string; // 是否激活
|
||||
updateTime?: string; // 更新时间
|
||||
ftenantId?: string; // 租户id
|
||||
fflowId?: string; // 流程id
|
||||
fflowTaskId?: string; // 流程任务主键
|
||||
fflowState?: number; // 流程任务状态
|
||||
}
|
||||
|
||||
export const erpAccountList = (params?: ErpAccount | any) =>
|
||||
defHttp.get<ErpAccount>({ url: adminPath + '/erp/account/list', params });
|
||||
|
||||
export const erpAccountListData = (params?: ErpAccount | any) =>
|
||||
defHttp.post<Page<ErpAccount>>({ url: adminPath + '/erp/account/listData', params });
|
||||
|
||||
export const erpAccountForm = (params?: ErpAccount | any) =>
|
||||
defHttp.get<ErpAccount>({ url: adminPath + '/erp/account/form', params });
|
||||
|
||||
export const erpAccountSave = (params?: any, data?: ErpAccount | any) =>
|
||||
defHttp.postJson<ErpAccount>({ url: adminPath + '/erp/account/save', params, data });
|
||||
|
||||
export const erpAccountImportData = (
|
||||
params: UploadFileParams,
|
||||
onUploadProgress: (progressEvent: AxiosProgressEvent) => void,
|
||||
) =>
|
||||
defHttp.uploadFile<UploadApiResult>(
|
||||
{
|
||||
url: ctxPath + adminPath + '/erp/account/importData',
|
||||
onUploadProgress,
|
||||
},
|
||||
params,
|
||||
);
|
||||
|
||||
export const erpAccountDelete = (params?: ErpAccount | any) =>
|
||||
defHttp.get<ErpAccount>({ url: adminPath + '/erp/account/delete', params });
|
||||
58
web-vue/packages/erp/api/erp/category.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
*/
|
||||
import { defHttp } from '@jeesite/core/utils/http/axios';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { BasicModel, Page } from '@jeesite/core/api/model/baseModel';
|
||||
import { UploadApiResult } from '@jeesite/core/api/sys/upload';
|
||||
import { UploadFileParams } from '@jeesite/types/axios';
|
||||
import { AxiosProgressEvent } from 'axios';
|
||||
|
||||
const { ctxPath, adminPath } = useGlobSetting();
|
||||
|
||||
export interface ErpCategory extends BasicModel<ErpCategory> {
|
||||
createTime: string; // 记录时间
|
||||
categoryId: string; // 分类标识
|
||||
categoryName: string; // 分类名称
|
||||
categoryType: string; // 分类类型
|
||||
parentId?: string; // 父级分类
|
||||
sortOrder: string; // 排序序号
|
||||
isActive: string; // 是否启用
|
||||
updateTime?: string; // 更新时间
|
||||
ftenantId: string; // 租户id
|
||||
fflowId?: string; // 流程id
|
||||
fflowTaskId?: string; // 流程任务主键
|
||||
fflowState?: number; // 流程任务状态
|
||||
}
|
||||
|
||||
export const erpCategoryList = (params?: ErpCategory | any) =>
|
||||
defHttp.get<ErpCategory>({ url: adminPath + '/erp/category/list', params });
|
||||
|
||||
export const erpCategoryListAll = (params?: ErpCategory | any) =>
|
||||
defHttp.get<ErpCategory[]>({ url: adminPath + '/erp/category/listAll', params });
|
||||
|
||||
export const erpCategoryListData = (params?: ErpCategory | any) =>
|
||||
defHttp.post<Page<ErpCategory>>({ url: adminPath + '/erp/category/listData', params });
|
||||
|
||||
export const erpCategoryForm = (params?: ErpCategory | any) =>
|
||||
defHttp.get<ErpCategory>({ url: adminPath + '/erp/category/form', params });
|
||||
|
||||
export const erpCategorySave = (params?: any, data?: ErpCategory | any) =>
|
||||
defHttp.postJson<ErpCategory>({ url: adminPath + '/erp/category/save', params, data });
|
||||
|
||||
export const erpCategoryImportData = (
|
||||
params: UploadFileParams,
|
||||
onUploadProgress: (progressEvent: AxiosProgressEvent) => void,
|
||||
) =>
|
||||
defHttp.uploadFile<UploadApiResult>(
|
||||
{
|
||||
url: ctxPath + adminPath + '/erp/category/importData',
|
||||
onUploadProgress,
|
||||
},
|
||||
params,
|
||||
);
|
||||
|
||||
export const erpCategoryDelete = (params?: ErpCategory | any) =>
|
||||
defHttp.get<ErpCategory>({ url: adminPath + '/erp/category/delete', params });
|
||||
54
web-vue/packages/erp/api/erp/expense.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
*/
|
||||
import { defHttp } from '@jeesite/core/utils/http/axios';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { BasicModel, Page } from '@jeesite/core/api/model/baseModel';
|
||||
import { UploadApiResult } from '@jeesite/core/api/sys/upload';
|
||||
import { UploadFileParams } from '@jeesite/types/axios';
|
||||
import { AxiosProgressEvent } from 'axios';
|
||||
|
||||
const { ctxPath, adminPath } = useGlobSetting();
|
||||
|
||||
export interface ErpExpense extends BasicModel<ErpExpense> {
|
||||
createTime?: string; // 记录时间
|
||||
expenseId?: string; // 支出ID
|
||||
zflowId: string; // 关联流水ID
|
||||
accountId: string; // 支出账户ID
|
||||
categoryId: string; // 支出分类ID
|
||||
amount: number; // 交易金额
|
||||
updateTime?: string; // 更新时间
|
||||
ftenantId?: string; // 租户id
|
||||
fflowId?: string; // 流程id
|
||||
fflowTaskId?: string; // 流程任务主键
|
||||
fflowState?: number; // 流程任务状态
|
||||
}
|
||||
|
||||
export const erpExpenseList = (params?: ErpExpense | any) =>
|
||||
defHttp.get<ErpExpense>({ url: adminPath + '/erp/expense/list', params });
|
||||
|
||||
export const erpExpenseListData = (params?: ErpExpense | any) =>
|
||||
defHttp.post<Page<ErpExpense>>({ url: adminPath + '/erp/expense/listData', params });
|
||||
|
||||
export const erpExpenseForm = (params?: ErpExpense | any) =>
|
||||
defHttp.get<ErpExpense>({ url: adminPath + '/erp/expense/form', params });
|
||||
|
||||
export const erpExpenseSave = (params?: any, data?: ErpExpense | any) =>
|
||||
defHttp.postJson<ErpExpense>({ url: adminPath + '/erp/expense/save', params, data });
|
||||
|
||||
export const erpExpenseImportData = (
|
||||
params: UploadFileParams,
|
||||
onUploadProgress: (progressEvent: AxiosProgressEvent) => void,
|
||||
) =>
|
||||
defHttp.uploadFile<UploadApiResult>(
|
||||
{
|
||||
url: ctxPath + adminPath + '/erp/expense/importData',
|
||||
onUploadProgress,
|
||||
},
|
||||
params,
|
||||
);
|
||||
|
||||
export const erpExpenseDelete = (params?: ErpExpense | any) =>
|
||||
defHttp.get<ErpExpense>({ url: adminPath + '/erp/expense/delete', params });
|
||||
54
web-vue/packages/erp/api/erp/income.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
*/
|
||||
import { defHttp } from '@jeesite/core/utils/http/axios';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { BasicModel, Page } from '@jeesite/core/api/model/baseModel';
|
||||
import { UploadApiResult } from '@jeesite/core/api/sys/upload';
|
||||
import { UploadFileParams } from '@jeesite/types/axios';
|
||||
import { AxiosProgressEvent } from 'axios';
|
||||
|
||||
const { ctxPath, adminPath } = useGlobSetting();
|
||||
|
||||
export interface ErpIncome extends BasicModel<ErpIncome> {
|
||||
createTime?: string; // 记录时间
|
||||
incomeId?: string; // 收入ID
|
||||
sflowId: string; // 关联流水ID
|
||||
accountId: string; // 收入账户ID
|
||||
categoryId: string; // 收入分类ID
|
||||
amount: number; // 交易金额(正数)
|
||||
updateTime?: string; // 更新时间
|
||||
ftenantId?: string; // 租户id
|
||||
fflowId?: string; // 流程id
|
||||
fflowTaskId?: string; // 流程任务主键
|
||||
fflowState?: number; // 流程任务状态
|
||||
}
|
||||
|
||||
export const erpIncomeList = (params?: ErpIncome | any) =>
|
||||
defHttp.get<ErpIncome>({ url: adminPath + '/erp/income/list', params });
|
||||
|
||||
export const erpIncomeListData = (params?: ErpIncome | any) =>
|
||||
defHttp.post<Page<ErpIncome>>({ url: adminPath + '/erp/income/listData', params });
|
||||
|
||||
export const erpIncomeForm = (params?: ErpIncome | any) =>
|
||||
defHttp.get<ErpIncome>({ url: adminPath + '/erp/income/form', params });
|
||||
|
||||
export const erpIncomeSave = (params?: any, data?: ErpIncome | any) =>
|
||||
defHttp.postJson<ErpIncome>({ url: adminPath + '/erp/income/save', params, data });
|
||||
|
||||
export const erpIncomeImportData = (
|
||||
params: UploadFileParams,
|
||||
onUploadProgress: (progressEvent: AxiosProgressEvent) => void,
|
||||
) =>
|
||||
defHttp.uploadFile<UploadApiResult>(
|
||||
{
|
||||
url: ctxPath + adminPath + '/erp/income/importData',
|
||||
onUploadProgress,
|
||||
},
|
||||
params,
|
||||
);
|
||||
|
||||
export const erpIncomeDelete = (params?: ErpIncome | any) =>
|
||||
defHttp.get<ErpIncome>({ url: adminPath + '/erp/income/delete', params });
|
||||
61
web-vue/packages/erp/api/erp/transactionFlow.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
*/
|
||||
import { defHttp } from '@jeesite/core/utils/http/axios';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { BasicModel, Page } from '@jeesite/core/api/model/baseModel';
|
||||
import { UploadApiResult } from '@jeesite/core/api/sys/upload';
|
||||
import { UploadFileParams } from '@jeesite/types/axios';
|
||||
import { AxiosProgressEvent } from 'axios';
|
||||
|
||||
const { ctxPath, adminPath } = useGlobSetting();
|
||||
|
||||
export interface ErpTransactionFlow extends BasicModel<ErpTransactionFlow> {
|
||||
createTime?: string; // 记录时间
|
||||
flowId?: string; // 流水编号
|
||||
flowName: string; // 交易名称
|
||||
transactionType: string; // 交易类型
|
||||
amount: number; // 交易金额
|
||||
transactionTime?: string; // 交易时间
|
||||
accountId: string; // 交易账户
|
||||
categoryId: string; // 交易分类
|
||||
remark?: string; // 交易备注
|
||||
isFinish?: string; // 是否记账
|
||||
updateTime?: string; // 更新时间
|
||||
ftenantId?: string; // 租户id
|
||||
fflowId?: string; // 流程id
|
||||
fflowTaskId?: string; // 流程任务主键
|
||||
fflowState?: number; // 流程任务状态
|
||||
}
|
||||
|
||||
export const erpTransactionFlowList = (params?: ErpTransactionFlow | any) =>
|
||||
defHttp.get<ErpTransactionFlow>({ url: adminPath + '/erp/transactionFlow/list', params });
|
||||
|
||||
export const erpTransactionFlowListData = (params?: ErpTransactionFlow | any) =>
|
||||
defHttp.post<Page<ErpTransactionFlow>>({ url: adminPath + '/erp/transactionFlow/listData', params });
|
||||
|
||||
export const erpTransactionFlowForm = (params?: ErpTransactionFlow | any) =>
|
||||
defHttp.get<ErpTransactionFlow>({ url: adminPath + '/erp/transactionFlow/form', params });
|
||||
|
||||
export const erpTransactionFlowSave = (params?: any, data?: ErpTransactionFlow | any) =>
|
||||
defHttp.postJson<ErpTransactionFlow>({ url: adminPath + '/erp/transactionFlow/save', params, data });
|
||||
|
||||
export const erpTransactionFlowImportData = (
|
||||
params: UploadFileParams,
|
||||
onUploadProgress: (progressEvent: AxiosProgressEvent) => void,
|
||||
) =>
|
||||
defHttp.uploadFile<UploadApiResult>(
|
||||
{
|
||||
url: ctxPath + adminPath + '/erp/transactionFlow/importData',
|
||||
onUploadProgress,
|
||||
},
|
||||
params,
|
||||
);
|
||||
|
||||
export const erpTransactionFlowDelete = (params?: ErpTransactionFlow | any) =>
|
||||
defHttp.get<ErpTransactionFlow>({ url: adminPath + '/erp/transactionFlow/delete', params });
|
||||
|
||||
export const erpTransactionFlowFinish = (params?: ErpTransactionFlow | any) =>
|
||||
defHttp.get<ErpTransactionFlow>({ url: adminPath + '/erp/transactionFlow/finish', params });
|
||||
30
web-vue/packages/erp/package.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "@jeesite/erp",
|
||||
"version": "5.14.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"type:check": "vue-tsc --noEmit --skipLibCheck",
|
||||
"uninstall": "rimraf node_modules",
|
||||
"update": "ncu -u"
|
||||
},
|
||||
"dependencies": {
|
||||
"qs": "6.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/qs": "6.9.18"
|
||||
},
|
||||
"homepage": "https://jeesite.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitee.com/thinkgem/jeesite-vue.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://gitee.com/thinkgem/jeesite-vue/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "ThinkGem",
|
||||
"email": "thinkgem@163.com",
|
||||
"url": "https://gitee.com/thinkgem"
|
||||
}
|
||||
}
|
||||
20
web-vue/packages/erp/tsconfig.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@jeesite/erp/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"./**/*.ts",
|
||||
"./**/*.tsx",
|
||||
"./**/*.vue"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"vite.config.ts",
|
||||
"_lib",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
143
web-vue/packages/erp/views/erp/account/form.vue
Normal file
@@ -0,0 +1,143 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
:showFooter="true"
|
||||
:okAuth="'erp:account:edit'"
|
||||
@register="registerDrawer"
|
||||
@ok="handleSubmit"
|
||||
width="40%"
|
||||
>
|
||||
<template #title>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsErpAccountForm">
|
||||
import { ref, unref, computed } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicForm, FormSchema, useForm } from '@jeesite/core/components/Form';
|
||||
import { BasicDrawer, useDrawerInner } from '@jeesite/core/components/Drawer';
|
||||
import { ErpAccount, erpAccountSave, erpAccountForm } from '@jeesite/erp/api/erp/account';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('erp.account');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<ErpAccount>({} as ErpAccount);
|
||||
|
||||
const getTitle = computed(() => ({
|
||||
icon: meta.icon || 'i-ant-design:book-outlined',
|
||||
value: record.value.isNewRecord ? t('新增账户信息') : t('编辑账户信息'),
|
||||
}));
|
||||
|
||||
const inputFormSchemas: FormSchema<ErpAccount>[] = [
|
||||
{
|
||||
label: t('账户名称'),
|
||||
field: 'accountName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 100,
|
||||
},
|
||||
required: true,
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('账户卡号'),
|
||||
field: 'accountCode',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 32,
|
||||
},
|
||||
required: true,
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('初始余额'),
|
||||
field: 'initialBalance',
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
maxlength: 10,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('当前余额'),
|
||||
field: 'currentBalance',
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
maxlength: 10,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('账户类型'),
|
||||
field: 'accountType',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'account_type',
|
||||
allowClear: true,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('是否激活'),
|
||||
field: 'isActive',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'is_active',
|
||||
allowClear: true,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
|
||||
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm<ErpAccount>({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas,
|
||||
baseColProps: { md: 24, lg: 12 },
|
||||
});
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
setDrawerProps({ loading: true });
|
||||
await resetFields();
|
||||
const res = await erpAccountForm(data);
|
||||
record.value = (res.erpAccount || {}) as ErpAccount;
|
||||
record.value.__t = new Date().getTime();
|
||||
await setFieldsValue(record.value);
|
||||
setDrawerProps({ loading: false });
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const data = await validate();
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
const params: any = {
|
||||
isNewRecord: record.value.isNewRecord,
|
||||
accountId: record.value.accountId || data.accountId,
|
||||
};
|
||||
// console.log('submit', params, data, record);
|
||||
const res = await erpAccountSave(params, data);
|
||||
showMessage(res.message);
|
||||
setTimeout(closeDrawer);
|
||||
emit('success', data);
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
103
web-vue/packages/erp/views/erp/account/formImport.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
:title="t('导入账户信息')"
|
||||
:okText="t('导入')"
|
||||
@register="registerModal"
|
||||
@ok="handleSubmit"
|
||||
:minHeight="120"
|
||||
:width="400"
|
||||
>
|
||||
<Upload accept=".xls,.xlsx" :file-list="fileList" :before-upload="beforeUpload" @remove="handleRemove">
|
||||
<a-button> <Icon icon="ant-design:upload-outlined" /> {{ t('选择文件') }} </a-button>
|
||||
<span class="ml-4">{{ uploadInfo }}</span>
|
||||
</Upload>
|
||||
<div class="ml-4 mt-4">
|
||||
{{ t('提示:仅允许导入“xls”或“xlsx”格式文件!') }}
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<a-button @click="handleDownloadTemplate()" type="text">
|
||||
<Icon icon="i-fa:file-excel-o" />
|
||||
{{ t('下载模板') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { Upload } from 'ant-design-vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { downloadByUrl } from '@jeesite/core/utils/file/download';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicModal, useModalInner } from '@jeesite/core/components/Modal';
|
||||
import { erpAccountImportData } from '@jeesite/erp/api/erp/account';
|
||||
import { FileType } from 'ant-design-vue/es/upload/interface';
|
||||
import { AxiosProgressEvent } from 'axios';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('erp.account');
|
||||
const { showMessage, showMessageModal } = useMessage();
|
||||
|
||||
const fileList = ref<FileType[]>([]);
|
||||
const uploadInfo = ref('');
|
||||
|
||||
const beforeUpload = (file: FileType) => {
|
||||
fileList.value = [file];
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleRemove = () => {
|
||||
fileList.value = [];
|
||||
};
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(() => {
|
||||
fileList.value = [];
|
||||
uploadInfo.value = '';
|
||||
});
|
||||
|
||||
async function handleDownloadTemplate() {
|
||||
const { ctxAdminPath } = useGlobSetting();
|
||||
downloadByUrl({ url: ctxAdminPath + '/erp/account/importTemplate' });
|
||||
}
|
||||
|
||||
function onUploadProgress(progressEvent: AxiosProgressEvent) {
|
||||
const complete = ((progressEvent.loaded / (progressEvent.total || 1)) * 100) | 0;
|
||||
if (complete != 100) {
|
||||
uploadInfo.value = t('正在导入,请稍候') + ' ' + complete + '%...';
|
||||
} else {
|
||||
uploadInfo.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
if (fileList.value.length == 0) {
|
||||
showMessage(t('请选择要导入的数据文件'));
|
||||
return;
|
||||
}
|
||||
setModalProps({ confirmLoading: true });
|
||||
const params = {
|
||||
file: fileList.value[0],
|
||||
};
|
||||
const { data } = await erpAccountImportData(params, onUploadProgress);
|
||||
showMessageModal({ content: data.message });
|
||||
setTimeout(closeModal);
|
||||
emit('success');
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
234
web-vue/packages/erp/views/erp/account/list.vue
Normal file
@@ -0,0 +1,234 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<a-button type="default" :loading="loading" @click="handleExport()">
|
||||
<Icon icon="i-ant-design:download-outlined" /> {{ t('导出') }}
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handleForm({})" v-auth="'erp:account:edit'">
|
||||
<Icon icon="i-fluent:add-12-filled" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #slotBizKey="{ record }">
|
||||
<a @click="handleForm({ accountId: record.accountId })" :title="record.accountName">
|
||||
{{ record.accountName }}
|
||||
</a>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<InputForm @register="registerDrawer" @success="handleSuccess" />
|
||||
<FormImport @register="registerImportModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsErpAccountList">
|
||||
import { onMounted, ref, unref } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { downloadByUrl } from '@jeesite/core/utils/file/download';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicTable, BasicColumn, useTable } from '@jeesite/core/components/Table';
|
||||
import { ErpAccount, erpAccountList } from '@jeesite/erp/api/erp/account';
|
||||
import { erpAccountDelete, erpAccountListData } from '@jeesite/erp/api/erp/account';
|
||||
import { useDrawer } from '@jeesite/core/components/Drawer';
|
||||
import { useModal } from '@jeesite/core/components/Modal';
|
||||
import { FormProps } from '@jeesite/core/components/Form';
|
||||
import InputForm from './form.vue';
|
||||
import FormImport from './formImport.vue';
|
||||
|
||||
const { t } = useI18n('erp.account');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<ErpAccount>({} as ErpAccount);
|
||||
|
||||
const getTitle = {
|
||||
icon: meta.icon || 'i-ant-design:book-outlined',
|
||||
value: meta.title || t('账户信息管理'),
|
||||
};
|
||||
const loading = ref(false);
|
||||
|
||||
const searchForm: FormProps<ErpAccount> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('账户名称'),
|
||||
field: 'accountName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('账户类型'),
|
||||
field: 'accountType',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'account_type',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('是否激活'),
|
||||
field: 'isActive',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'is_active',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<ErpAccount>[] = [
|
||||
{
|
||||
title: t('记录时间'),
|
||||
dataIndex: 'createTime',
|
||||
key: 'a.create_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('账户名称'),
|
||||
dataIndex: 'accountName',
|
||||
key: 'a.account_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
slot: 'slotBizKey',
|
||||
},
|
||||
{
|
||||
title: t('账户类型'),
|
||||
dataIndex: 'accountType',
|
||||
key: 'a.account_type',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'account_type',
|
||||
},
|
||||
{
|
||||
title: t('账户卡号'),
|
||||
dataIndex: 'accountCode',
|
||||
key: 'a.account_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('初始余额'),
|
||||
dataIndex: 'initialBalance',
|
||||
key: 'a.initial_balance',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
title: t('当前余额'),
|
||||
dataIndex: 'currentBalance',
|
||||
key: 'a.current_balance',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
title: t('是否激活'),
|
||||
dataIndex: 'isActive',
|
||||
key: 'a.is_active',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'is_active',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
key: 'a.update_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
|
||||
const actionColumn: BasicColumn<ErpAccount> = {
|
||||
width: 160,
|
||||
align: 'center',
|
||||
actions: (record: ErpAccount) => [
|
||||
{
|
||||
icon: 'i-clarity:note-edit-line',
|
||||
title: t('编辑'),
|
||||
onClick: handleForm.bind(this, { accountId: record.accountId }),
|
||||
auth: 'erp:account:edit',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
title: t('删除'),
|
||||
popConfirm: {
|
||||
title: t('是否确认删除账户?'),
|
||||
confirm: handleDelete.bind(this, record),
|
||||
},
|
||||
auth: 'erp:account:edit',
|
||||
ifShow: record.isActive == '0'
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const [registerTable, { reload, getForm }] = useTable<ErpAccount>({
|
||||
api: erpAccountListData,
|
||||
beforeFetch: (params) => {
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
actionColumn: actionColumn,
|
||||
formConfig: searchForm,
|
||||
showTableSetting: true,
|
||||
useSearchForm: true,
|
||||
canResize: true,
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const res = await erpAccountList();
|
||||
record.value = (res.erpAccount || {}) as ErpAccount;
|
||||
await getForm().setFieldsValue(record.value);
|
||||
});
|
||||
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
|
||||
function handleForm(record: Recordable) {
|
||||
openDrawer(true, record);
|
||||
}
|
||||
|
||||
async function handleExport() {
|
||||
loading.value = true;
|
||||
const { ctxAdminPath } = useGlobSetting();
|
||||
await downloadByUrl({
|
||||
url: ctxAdminPath + '/erp/account/exportData',
|
||||
params: getForm().getFieldsValue(),
|
||||
});
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
const [registerImportModal, { openModal: importModal }] = useModal();
|
||||
|
||||
function handleImport() {
|
||||
importModal(true, {});
|
||||
}
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
const params = { accountId: record.accountId };
|
||||
const res = await erpAccountDelete(params);
|
||||
showMessage(res.message);
|
||||
await handleSuccess(record);
|
||||
}
|
||||
|
||||
async function handleSuccess(record: Recordable) {
|
||||
await reload({ record });
|
||||
}
|
||||
</script>
|
||||
142
web-vue/packages/erp/views/erp/category/form.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
:showFooter="true"
|
||||
:okAuth="'erp:category:edit'"
|
||||
@register="registerDrawer"
|
||||
@ok="handleSubmit"
|
||||
width="40%"
|
||||
>
|
||||
<template #title>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsErpCategoryForm">
|
||||
import { ref, unref, computed } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicForm, FormSchema, useForm } from '@jeesite/core/components/Form';
|
||||
import { BasicDrawer, useDrawerInner } from '@jeesite/core/components/Drawer';
|
||||
import { ErpCategory, erpCategorySave, erpCategoryForm } from '@jeesite/erp/api/erp/category';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('erp.category');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<ErpCategory>({} as ErpCategory);
|
||||
|
||||
const getTitle = computed(() => ({
|
||||
icon: meta.icon || 'i-ant-design:book-outlined',
|
||||
value: record.value.isNewRecord ? t('新增分类信息') : t('编辑分类信息'),
|
||||
}));
|
||||
|
||||
const inputFormSchemas: FormSchema<ErpCategory>[] = [
|
||||
{
|
||||
label: t('记录时间'),
|
||||
field: 'createTime',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('分类名称'),
|
||||
field: 'categoryName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 50,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('分类类型'),
|
||||
field: 'categoryType',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'category_type',
|
||||
allowClear: true,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('父级分类'),
|
||||
field: 'parentId',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'parent_type',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('排序序号'),
|
||||
field: 'sortOrder',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 32,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('是否启用'),
|
||||
field: 'isActive',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'is_active',
|
||||
allowClear: true,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
|
||||
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm<ErpCategory>({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas,
|
||||
baseColProps: { md: 24, lg: 12 },
|
||||
});
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
setDrawerProps({ loading: true });
|
||||
await resetFields();
|
||||
const res = await erpCategoryForm(data);
|
||||
record.value = (res.erpCategory || {}) as ErpCategory;
|
||||
record.value.__t = new Date().getTime();
|
||||
await setFieldsValue(record.value);
|
||||
setDrawerProps({ loading: false });
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const data = await validate();
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
const params: any = {
|
||||
isNewRecord: record.value.isNewRecord,
|
||||
categoryId: record.value.categoryId || data.categoryId,
|
||||
};
|
||||
// console.log('submit', params, data, record);
|
||||
const res = await erpCategorySave(params, data);
|
||||
showMessage(res.message);
|
||||
setTimeout(closeDrawer);
|
||||
emit('success', data);
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
103
web-vue/packages/erp/views/erp/category/formImport.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
:title="t('导入分类信息')"
|
||||
:okText="t('导入')"
|
||||
@register="registerModal"
|
||||
@ok="handleSubmit"
|
||||
:minHeight="120"
|
||||
:width="400"
|
||||
>
|
||||
<Upload accept=".xls,.xlsx" :file-list="fileList" :before-upload="beforeUpload" @remove="handleRemove">
|
||||
<a-button> <Icon icon="ant-design:upload-outlined" /> {{ t('选择文件') }} </a-button>
|
||||
<span class="ml-4">{{ uploadInfo }}</span>
|
||||
</Upload>
|
||||
<div class="ml-4 mt-4">
|
||||
{{ t('提示:仅允许导入“xls”或“xlsx”格式文件!') }}
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<a-button @click="handleDownloadTemplate()" type="text">
|
||||
<Icon icon="i-fa:file-excel-o" />
|
||||
{{ t('下载模板') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { Upload } from 'ant-design-vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { downloadByUrl } from '@jeesite/core/utils/file/download';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicModal, useModalInner } from '@jeesite/core/components/Modal';
|
||||
import { erpCategoryImportData } from '@jeesite/erp/api/erp/category';
|
||||
import { FileType } from 'ant-design-vue/es/upload/interface';
|
||||
import { AxiosProgressEvent } from 'axios';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('erp.category');
|
||||
const { showMessage, showMessageModal } = useMessage();
|
||||
|
||||
const fileList = ref<FileType[]>([]);
|
||||
const uploadInfo = ref('');
|
||||
|
||||
const beforeUpload = (file: FileType) => {
|
||||
fileList.value = [file];
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleRemove = () => {
|
||||
fileList.value = [];
|
||||
};
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(() => {
|
||||
fileList.value = [];
|
||||
uploadInfo.value = '';
|
||||
});
|
||||
|
||||
async function handleDownloadTemplate() {
|
||||
const { ctxAdminPath } = useGlobSetting();
|
||||
downloadByUrl({ url: ctxAdminPath + '/erp/category/importTemplate' });
|
||||
}
|
||||
|
||||
function onUploadProgress(progressEvent: AxiosProgressEvent) {
|
||||
const complete = ((progressEvent.loaded / (progressEvent.total || 1)) * 100) | 0;
|
||||
if (complete != 100) {
|
||||
uploadInfo.value = t('正在导入,请稍候') + ' ' + complete + '%...';
|
||||
} else {
|
||||
uploadInfo.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
if (fileList.value.length == 0) {
|
||||
showMessage(t('请选择要导入的数据文件'));
|
||||
return;
|
||||
}
|
||||
setModalProps({ confirmLoading: true });
|
||||
const params = {
|
||||
file: fileList.value[0],
|
||||
};
|
||||
const { data } = await erpCategoryImportData(params, onUploadProgress);
|
||||
showMessageModal({ content: data.message });
|
||||
setTimeout(closeModal);
|
||||
emit('success');
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
227
web-vue/packages/erp/views/erp/category/list.vue
Normal file
@@ -0,0 +1,227 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<a-button type="default" :loading="loading" @click="handleExport()">
|
||||
<Icon icon="i-ant-design:download-outlined" /> {{ t('导出') }}
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handleForm({})" v-auth="'erp:category:edit'">
|
||||
<Icon icon="i-fluent:add-12-filled" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #slotBizKey="{ record }">
|
||||
<a @click="handleForm({ categoryId: record.categoryId })" :title="record.categoryName">
|
||||
{{ record.categoryName }}
|
||||
</a>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<InputForm @register="registerDrawer" @success="handleSuccess" />
|
||||
<FormImport @register="registerImportModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsErpCategoryList">
|
||||
import { onMounted, ref, unref } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { downloadByUrl } from '@jeesite/core/utils/file/download';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicTable, BasicColumn, useTable } from '@jeesite/core/components/Table';
|
||||
import { ErpCategory, erpCategoryList } from '@jeesite/erp/api/erp/category';
|
||||
import { erpCategoryDelete, erpCategoryListData } from '@jeesite/erp/api/erp/category';
|
||||
import { useDrawer } from '@jeesite/core/components/Drawer';
|
||||
import { useModal } from '@jeesite/core/components/Modal';
|
||||
import { FormProps } from '@jeesite/core/components/Form';
|
||||
import InputForm from './form.vue';
|
||||
import FormImport from './formImport.vue';
|
||||
|
||||
const { t } = useI18n('erp.category');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<ErpCategory>({} as ErpCategory);
|
||||
|
||||
const getTitle = {
|
||||
icon: meta.icon || 'i-ant-design:book-outlined',
|
||||
value: meta.title || t('分类信息管理'),
|
||||
};
|
||||
const loading = ref(false);
|
||||
|
||||
const searchForm: FormProps<ErpCategory> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('分类名称'),
|
||||
field: 'categoryName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('分类类型'),
|
||||
field: 'categoryType',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'category_type',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('是否启用'),
|
||||
field: 'isActive',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'is_active',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<ErpCategory>[] = [
|
||||
{
|
||||
title: t('记录时间'),
|
||||
dataIndex: 'createTime',
|
||||
key: 'a.create_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('分类名称'),
|
||||
dataIndex: 'categoryName',
|
||||
key: 'a.category_name',
|
||||
sorter: true,
|
||||
width: 200,
|
||||
align: 'left',
|
||||
slot: 'slotBizKey',
|
||||
},
|
||||
{
|
||||
title: t('分类类型'),
|
||||
dataIndex: 'categoryType',
|
||||
key: 'a.category_type',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'category_type',
|
||||
},
|
||||
{
|
||||
title: t('父级分类'),
|
||||
dataIndex: 'parentId',
|
||||
key: 'a.parent_id',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'parent_type',
|
||||
},
|
||||
{
|
||||
title: t('排序序号'),
|
||||
dataIndex: 'sortOrder',
|
||||
key: 'a.sort_order',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('是否启用'),
|
||||
dataIndex: 'isActive',
|
||||
key: 'a.is_active',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'is_active',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
key: 'a.update_time',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
|
||||
const actionColumn: BasicColumn<ErpCategory> = {
|
||||
width: 160,
|
||||
align: 'center',
|
||||
actions: (record: ErpCategory) => [
|
||||
{
|
||||
icon: 'i-clarity:note-edit-line',
|
||||
title: t('编辑'),
|
||||
onClick: handleForm.bind(this, { categoryId: record.categoryId }),
|
||||
auth: 'erp:category:edit',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
title: t('删除'),
|
||||
popConfirm: {
|
||||
title: t('是否确认删除分类信息?'),
|
||||
confirm: handleDelete.bind(this, record),
|
||||
},
|
||||
auth: 'erp:category:edit',
|
||||
ifShow: record.isActive == '0'
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const [registerTable, { reload, getForm }] = useTable<ErpCategory>({
|
||||
api: erpCategoryListData,
|
||||
beforeFetch: (params) => {
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
actionColumn: actionColumn,
|
||||
formConfig: searchForm,
|
||||
showTableSetting: true,
|
||||
useSearchForm: true,
|
||||
canResize: true,
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const res = await erpCategoryList();
|
||||
record.value = (res.erpCategory || {}) as ErpCategory;
|
||||
await getForm().setFieldsValue(record.value);
|
||||
});
|
||||
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
|
||||
function handleForm(record: Recordable) {
|
||||
openDrawer(true, record);
|
||||
}
|
||||
|
||||
async function handleExport() {
|
||||
loading.value = true;
|
||||
const { ctxAdminPath } = useGlobSetting();
|
||||
await downloadByUrl({
|
||||
url: ctxAdminPath + '/erp/category/exportData',
|
||||
params: getForm().getFieldsValue(),
|
||||
});
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
const [registerImportModal, { openModal: importModal }] = useModal();
|
||||
|
||||
function handleImport() {
|
||||
importModal(true, {});
|
||||
}
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
const params = { categoryId: record.categoryId };
|
||||
const res = await erpCategoryDelete(params);
|
||||
showMessage(res.message);
|
||||
await handleSuccess(record);
|
||||
}
|
||||
|
||||
async function handleSuccess(record: Recordable) {
|
||||
await reload({ record });
|
||||
}
|
||||
</script>
|
||||
103
web-vue/packages/erp/views/erp/expense/formImport.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
:title="t('导入支出信息')"
|
||||
:okText="t('导入')"
|
||||
@register="registerModal"
|
||||
@ok="handleSubmit"
|
||||
:minHeight="120"
|
||||
:width="400"
|
||||
>
|
||||
<Upload accept=".xls,.xlsx" :file-list="fileList" :before-upload="beforeUpload" @remove="handleRemove">
|
||||
<a-button> <Icon icon="ant-design:upload-outlined" /> {{ t('选择文件') }} </a-button>
|
||||
<span class="ml-4">{{ uploadInfo }}</span>
|
||||
</Upload>
|
||||
<div class="ml-4 mt-4">
|
||||
{{ t('提示:仅允许导入“xls”或“xlsx”格式文件!') }}
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<a-button @click="handleDownloadTemplate()" type="text">
|
||||
<Icon icon="i-fa:file-excel-o" />
|
||||
{{ t('下载模板') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { Upload } from 'ant-design-vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { downloadByUrl } from '@jeesite/core/utils/file/download';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicModal, useModalInner } from '@jeesite/core/components/Modal';
|
||||
import { erpExpenseImportData } from '@jeesite/erp/api/erp/expense';
|
||||
import { FileType } from 'ant-design-vue/es/upload/interface';
|
||||
import { AxiosProgressEvent } from 'axios';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('erp.expense');
|
||||
const { showMessage, showMessageModal } = useMessage();
|
||||
|
||||
const fileList = ref<FileType[]>([]);
|
||||
const uploadInfo = ref('');
|
||||
|
||||
const beforeUpload = (file: FileType) => {
|
||||
fileList.value = [file];
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleRemove = () => {
|
||||
fileList.value = [];
|
||||
};
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(() => {
|
||||
fileList.value = [];
|
||||
uploadInfo.value = '';
|
||||
});
|
||||
|
||||
async function handleDownloadTemplate() {
|
||||
const { ctxAdminPath } = useGlobSetting();
|
||||
downloadByUrl({ url: ctxAdminPath + '/erp/expense/importTemplate' });
|
||||
}
|
||||
|
||||
function onUploadProgress(progressEvent: AxiosProgressEvent) {
|
||||
const complete = ((progressEvent.loaded / (progressEvent.total || 1)) * 100) | 0;
|
||||
if (complete != 100) {
|
||||
uploadInfo.value = t('正在导入,请稍候') + ' ' + complete + '%...';
|
||||
} else {
|
||||
uploadInfo.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
if (fileList.value.length == 0) {
|
||||
showMessage(t('请选择要导入的数据文件'));
|
||||
return;
|
||||
}
|
||||
setModalProps({ confirmLoading: true });
|
||||
const params = {
|
||||
file: fileList.value[0],
|
||||
};
|
||||
const { data } = await erpExpenseImportData(params, onUploadProgress);
|
||||
showMessageModal({ content: data.message });
|
||||
setTimeout(closeModal);
|
||||
emit('success');
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
213
web-vue/packages/erp/views/erp/expense/list.vue
Normal file
@@ -0,0 +1,213 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<a-button type="default" :loading="loading" @click="handleExport()">
|
||||
<Icon icon="i-ant-design:download-outlined" /> {{ t('导出') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<InputForm @register="registerDrawer" @success="handleSuccess" />
|
||||
<FormImport @register="registerImportModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsErpExpenseList">
|
||||
import { onMounted, ref, unref } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { downloadByUrl } from '@jeesite/core/utils/file/download';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicTable, BasicColumn, useTable } from '@jeesite/core/components/Table';
|
||||
import { ErpExpense, erpExpenseList } from '@jeesite/erp/api/erp/expense';
|
||||
import { erpExpenseDelete, erpExpenseListData } from '@jeesite/erp/api/erp/expense';
|
||||
import { useDrawer } from '@jeesite/core/components/Drawer';
|
||||
import { useModal } from '@jeesite/core/components/Modal';
|
||||
import { FormProps } from '@jeesite/core/components/Form';
|
||||
import FormImport from './formImport.vue';
|
||||
|
||||
const { t } = useI18n('erp.expense');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<ErpExpense>({} as ErpExpense);
|
||||
|
||||
const getTitle = {
|
||||
icon: meta.icon || 'i-ant-design:book-outlined',
|
||||
value: meta.title || t('支出信息管理'),
|
||||
};
|
||||
const loading = ref(false);
|
||||
|
||||
const searchForm: FormProps<ErpExpense> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('记录时间起'),
|
||||
field: 'createTime_gte',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('记录时间止'),
|
||||
field: 'createTime_lte',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('交易分类'),
|
||||
field: 'categoryId',
|
||||
fieldLabel: 'categoryName',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
selectType: 'erpCategorySelect',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<ErpExpense>[] = [
|
||||
{
|
||||
title: t('记录时间'),
|
||||
dataIndex: 'createTime',
|
||||
key: 'a.create_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('交易账号'),
|
||||
dataIndex: 'accountName',
|
||||
key: 'b.account_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('父级分类'),
|
||||
dataIndex: 'parentId',
|
||||
key: 'c.parent_id',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'parent_type',
|
||||
},
|
||||
{
|
||||
title: t('分类名称'),
|
||||
dataIndex: 'categoryName',
|
||||
key: 'c.category_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('交易名称'),
|
||||
dataIndex: 'flowName',
|
||||
key: 'd.flow_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('交易金额'),
|
||||
dataIndex: 'amount',
|
||||
key: 'a.amount',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
key: 'a.update_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
|
||||
const actionColumn: BasicColumn<ErpExpense> = {
|
||||
width: 160,
|
||||
align: 'center',
|
||||
actions: (record: ErpExpense) => [
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
title: t('删除'),
|
||||
popConfirm: {
|
||||
title: t('是否确认删除支出信息?'),
|
||||
confirm: handleDelete.bind(this, record),
|
||||
},
|
||||
auth: 'erp:expense:edit',
|
||||
ifShow: record.isFinish == '0'
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const [registerTable, { reload, getForm }] = useTable<ErpExpense>({
|
||||
api: erpExpenseListData,
|
||||
beforeFetch: (params) => {
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
actionColumn: actionColumn,
|
||||
formConfig: searchForm,
|
||||
showTableSetting: true,
|
||||
useSearchForm: true,
|
||||
canResize: true,
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const res = await erpExpenseList();
|
||||
record.value = (res.erpExpense || {}) as ErpExpense;
|
||||
await getForm().setFieldsValue(record.value);
|
||||
});
|
||||
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
|
||||
function handleForm(record: Recordable) {
|
||||
openDrawer(true, record);
|
||||
}
|
||||
|
||||
async function handleExport() {
|
||||
loading.value = true;
|
||||
const { ctxAdminPath } = useGlobSetting();
|
||||
await downloadByUrl({
|
||||
url: ctxAdminPath + '/erp/expense/exportData',
|
||||
params: getForm().getFieldsValue(),
|
||||
});
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
const [registerImportModal, { openModal: importModal }] = useModal();
|
||||
|
||||
function handleImport() {
|
||||
importModal(true, {});
|
||||
}
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
const params = { expenseId: record.expenseId };
|
||||
const res = await erpExpenseDelete(params);
|
||||
showMessage(res.message);
|
||||
await handleSuccess(record);
|
||||
}
|
||||
|
||||
async function handleSuccess(record: Recordable) {
|
||||
await reload({ record });
|
||||
}
|
||||
</script>
|
||||
103
web-vue/packages/erp/views/erp/income/formImport.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
:title="t('导入收入信息')"
|
||||
:okText="t('导入')"
|
||||
@register="registerModal"
|
||||
@ok="handleSubmit"
|
||||
:minHeight="120"
|
||||
:width="400"
|
||||
>
|
||||
<Upload accept=".xls,.xlsx" :file-list="fileList" :before-upload="beforeUpload" @remove="handleRemove">
|
||||
<a-button> <Icon icon="ant-design:upload-outlined" /> {{ t('选择文件') }} </a-button>
|
||||
<span class="ml-4">{{ uploadInfo }}</span>
|
||||
</Upload>
|
||||
<div class="ml-4 mt-4">
|
||||
{{ t('提示:仅允许导入“xls”或“xlsx”格式文件!') }}
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<a-button @click="handleDownloadTemplate()" type="text">
|
||||
<Icon icon="i-fa:file-excel-o" />
|
||||
{{ t('下载模板') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { Upload } from 'ant-design-vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { downloadByUrl } from '@jeesite/core/utils/file/download';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicModal, useModalInner } from '@jeesite/core/components/Modal';
|
||||
import { erpIncomeImportData } from '@jeesite/erp/api/erp/income';
|
||||
import { FileType } from 'ant-design-vue/es/upload/interface';
|
||||
import { AxiosProgressEvent } from 'axios';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('erp.income');
|
||||
const { showMessage, showMessageModal } = useMessage();
|
||||
|
||||
const fileList = ref<FileType[]>([]);
|
||||
const uploadInfo = ref('');
|
||||
|
||||
const beforeUpload = (file: FileType) => {
|
||||
fileList.value = [file];
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleRemove = () => {
|
||||
fileList.value = [];
|
||||
};
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(() => {
|
||||
fileList.value = [];
|
||||
uploadInfo.value = '';
|
||||
});
|
||||
|
||||
async function handleDownloadTemplate() {
|
||||
const { ctxAdminPath } = useGlobSetting();
|
||||
downloadByUrl({ url: ctxAdminPath + '/erp/income/importTemplate' });
|
||||
}
|
||||
|
||||
function onUploadProgress(progressEvent: AxiosProgressEvent) {
|
||||
const complete = ((progressEvent.loaded / (progressEvent.total || 1)) * 100) | 0;
|
||||
if (complete != 100) {
|
||||
uploadInfo.value = t('正在导入,请稍候') + ' ' + complete + '%...';
|
||||
} else {
|
||||
uploadInfo.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
if (fileList.value.length == 0) {
|
||||
showMessage(t('请选择要导入的数据文件'));
|
||||
return;
|
||||
}
|
||||
setModalProps({ confirmLoading: true });
|
||||
const params = {
|
||||
file: fileList.value[0],
|
||||
};
|
||||
const { data } = await erpIncomeImportData(params, onUploadProgress);
|
||||
showMessageModal({ content: data.message });
|
||||
setTimeout(closeModal);
|
||||
emit('success');
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
213
web-vue/packages/erp/views/erp/income/list.vue
Normal file
@@ -0,0 +1,213 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<a-button type="default" :loading="loading" @click="handleExport()">
|
||||
<Icon icon="i-ant-design:download-outlined" /> {{ t('导出') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<InputForm @register="registerDrawer" @success="handleSuccess" />
|
||||
<FormImport @register="registerImportModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsErpIncomeList">
|
||||
import { onMounted, ref, unref } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { downloadByUrl } from '@jeesite/core/utils/file/download';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicTable, BasicColumn, useTable } from '@jeesite/core/components/Table';
|
||||
import { ErpIncome, erpIncomeList } from '@jeesite/erp/api/erp/income';
|
||||
import { erpIncomeDelete, erpIncomeListData } from '@jeesite/erp/api/erp/income';
|
||||
import { useDrawer } from '@jeesite/core/components/Drawer';
|
||||
import { useModal } from '@jeesite/core/components/Modal';
|
||||
import { FormProps } from '@jeesite/core/components/Form';
|
||||
import FormImport from './formImport.vue';
|
||||
|
||||
const { t } = useI18n('erp.income');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<ErpIncome>({} as ErpIncome);
|
||||
|
||||
const getTitle = {
|
||||
icon: meta.icon || 'i-ant-design:book-outlined',
|
||||
value: meta.title || t('收入信息管理'),
|
||||
};
|
||||
const loading = ref(false);
|
||||
|
||||
const searchForm: FormProps<ErpIncome> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('记录时间起'),
|
||||
field: 'createTime_gte',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('记录时间止'),
|
||||
field: 'createTime_lte',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('交易分类'),
|
||||
field: 'categoryId',
|
||||
fieldLabel: 'categoryName',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
selectType: 'erpCategorySelect',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<ErpIncome>[] = [
|
||||
{
|
||||
title: t('记录时间'),
|
||||
dataIndex: 'createTime',
|
||||
key: 'a.create_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('交易账号'),
|
||||
dataIndex: 'accountName',
|
||||
key: 'b.account_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('父级分类'),
|
||||
dataIndex: 'parentId',
|
||||
key: 'c.parent_id',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'parent_type',
|
||||
},
|
||||
{
|
||||
title: t('分类名称'),
|
||||
dataIndex: 'categoryName',
|
||||
key: 'c.category_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('交易名称'),
|
||||
dataIndex: 'flowName',
|
||||
key: 'd.flow_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('交易金额'),
|
||||
dataIndex: 'amount',
|
||||
key: 'a.amount',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
key: 'a.update_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
|
||||
const actionColumn: BasicColumn<ErpIncome> = {
|
||||
width: 160,
|
||||
align: 'center',
|
||||
actions: (record: ErpIncome) => [
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
title: t('删除'),
|
||||
popConfirm: {
|
||||
title: t('是否确认删除收入信息?'),
|
||||
confirm: handleDelete.bind(this, record),
|
||||
},
|
||||
auth: 'erp:income:edit',
|
||||
ifShow: record.isFinish == '0'
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const [registerTable, { reload, getForm }] = useTable<ErpIncome>({
|
||||
api: erpIncomeListData,
|
||||
beforeFetch: (params) => {
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
actionColumn: actionColumn,
|
||||
formConfig: searchForm,
|
||||
showTableSetting: true,
|
||||
useSearchForm: true,
|
||||
canResize: true,
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const res = await erpIncomeList();
|
||||
record.value = (res.erpIncome || {}) as ErpIncome;
|
||||
await getForm().setFieldsValue(record.value);
|
||||
});
|
||||
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
|
||||
function handleForm(record: Recordable) {
|
||||
openDrawer(true, record);
|
||||
}
|
||||
|
||||
async function handleExport() {
|
||||
loading.value = true;
|
||||
const { ctxAdminPath } = useGlobSetting();
|
||||
await downloadByUrl({
|
||||
url: ctxAdminPath + '/erp/income/exportData',
|
||||
params: getForm().getFieldsValue(),
|
||||
});
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
const [registerImportModal, { openModal: importModal }] = useModal();
|
||||
|
||||
function handleImport() {
|
||||
importModal(true, {});
|
||||
}
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
const params = { incomeId: record.incomeId };
|
||||
const res = await erpIncomeDelete(params);
|
||||
showMessage(res.message);
|
||||
await handleSuccess(record);
|
||||
}
|
||||
|
||||
async function handleSuccess(record: Recordable) {
|
||||
await reload({ record });
|
||||
}
|
||||
</script>
|
||||
153
web-vue/packages/erp/views/erp/transactionFlow/form.vue
Normal file
@@ -0,0 +1,153 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
:showFooter="true"
|
||||
:okAuth="'erp:transactionFlow:edit'"
|
||||
@register="registerDrawer"
|
||||
@ok="handleSubmit"
|
||||
width="70%"
|
||||
>
|
||||
<template #title>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsErpTransactionFlowForm">
|
||||
import { ref, unref, computed } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicForm, FormSchema, useForm } from '@jeesite/core/components/Form';
|
||||
import { BasicDrawer, useDrawerInner } from '@jeesite/core/components/Drawer';
|
||||
import { ErpCategory, erpCategoryListAll } from '@jeesite/erp/api/erp/category';
|
||||
import { ErpTransactionFlow, erpTransactionFlowSave, erpTransactionFlowForm } from '@jeesite/erp/api/erp/transactionFlow';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('erp.transactionFlow');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<ErpTransactionFlow>({} as ErpTransactionFlow);
|
||||
|
||||
const categoryParams = ref<Recordable>({ categoryType: '' });
|
||||
|
||||
const getTitle = computed(() => ({
|
||||
icon: meta.icon || 'i-ant-design:book-outlined',
|
||||
value: record.value.isNewRecord ? t('新增明细信息') : t('编辑明细信息'),
|
||||
}));
|
||||
|
||||
const inputFormSchemas: FormSchema<ErpTransactionFlow>[] = [
|
||||
{
|
||||
label: t('交易名称'),
|
||||
field: 'flowName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 32,
|
||||
},
|
||||
required: true,
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('交易类型'),
|
||||
field: 'transactionType',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'transaction_type',
|
||||
allowClear: true,
|
||||
immediate: true,
|
||||
onChange:(value: string) => {
|
||||
categoryParams.value.categoryType = value
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('交易分类'),
|
||||
field: 'categoryId',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
api: erpCategoryListAll,
|
||||
params: categoryParams.value,
|
||||
fieldNames: { label: 'categoryName', value: 'categoryId' },
|
||||
allowClear: true,
|
||||
immediate: true,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('交易账户'),
|
||||
field: 'accountId',
|
||||
fieldLabel: 'accountName',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
selectType: 'erpAccountSelect',
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('交易金额'),
|
||||
field: 'amount',
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
maxlength: 10,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('交易备注'),
|
||||
field: 'remark',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
maxlength: 500,
|
||||
},
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
];
|
||||
|
||||
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm<ErpTransactionFlow>({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas,
|
||||
baseColProps: { md: 24, lg: 12 },
|
||||
});
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
setDrawerProps({ loading: true });
|
||||
await resetFields();
|
||||
const res = await erpTransactionFlowForm(data);
|
||||
record.value = (res.erpTransactionFlow || {}) as ErpTransactionFlow;
|
||||
record.value.__t = new Date().getTime();
|
||||
await setFieldsValue(record.value);
|
||||
setDrawerProps({ loading: false });
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const data = await validate();
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
const params: any = {
|
||||
isNewRecord: record.value.isNewRecord,
|
||||
flowId: record.value.flowId || data.flowId,
|
||||
};
|
||||
// console.log('submit', params, data, record);
|
||||
const res = await erpTransactionFlowSave(params, data);
|
||||
showMessage(res.message);
|
||||
setTimeout(closeDrawer);
|
||||
emit('success', data);
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
103
web-vue/packages/erp/views/erp/transactionFlow/formImport.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
:title="t('导入明细信息')"
|
||||
:okText="t('导入')"
|
||||
@register="registerModal"
|
||||
@ok="handleSubmit"
|
||||
:minHeight="120"
|
||||
:width="400"
|
||||
>
|
||||
<Upload accept=".xls,.xlsx" :file-list="fileList" :before-upload="beforeUpload" @remove="handleRemove">
|
||||
<a-button> <Icon icon="ant-design:upload-outlined" /> {{ t('选择文件') }} </a-button>
|
||||
<span class="ml-4">{{ uploadInfo }}</span>
|
||||
</Upload>
|
||||
<div class="ml-4 mt-4">
|
||||
{{ t('提示:仅允许导入“xls”或“xlsx”格式文件!') }}
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<a-button @click="handleDownloadTemplate()" type="text">
|
||||
<Icon icon="i-fa:file-excel-o" />
|
||||
{{ t('下载模板') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { Upload } from 'ant-design-vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { downloadByUrl } from '@jeesite/core/utils/file/download';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicModal, useModalInner } from '@jeesite/core/components/Modal';
|
||||
import { erpTransactionFlowImportData } from '@jeesite/erp/api/erp/transactionFlow';
|
||||
import { FileType } from 'ant-design-vue/es/upload/interface';
|
||||
import { AxiosProgressEvent } from 'axios';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('erp.transactionFlow');
|
||||
const { showMessage, showMessageModal } = useMessage();
|
||||
|
||||
const fileList = ref<FileType[]>([]);
|
||||
const uploadInfo = ref('');
|
||||
|
||||
const beforeUpload = (file: FileType) => {
|
||||
fileList.value = [file];
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleRemove = () => {
|
||||
fileList.value = [];
|
||||
};
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(() => {
|
||||
fileList.value = [];
|
||||
uploadInfo.value = '';
|
||||
});
|
||||
|
||||
async function handleDownloadTemplate() {
|
||||
const { ctxAdminPath } = useGlobSetting();
|
||||
downloadByUrl({ url: ctxAdminPath + '/erp/transactionFlow/importTemplate' });
|
||||
}
|
||||
|
||||
function onUploadProgress(progressEvent: AxiosProgressEvent) {
|
||||
const complete = ((progressEvent.loaded / (progressEvent.total || 1)) * 100) | 0;
|
||||
if (complete != 100) {
|
||||
uploadInfo.value = t('正在导入,请稍候') + ' ' + complete + '%...';
|
||||
} else {
|
||||
uploadInfo.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
if (fileList.value.length == 0) {
|
||||
showMessage(t('请选择要导入的数据文件'));
|
||||
return;
|
||||
}
|
||||
setModalProps({ confirmLoading: true });
|
||||
const params = {
|
||||
file: fileList.value[0],
|
||||
};
|
||||
const { data } = await erpTransactionFlowImportData(params, onUploadProgress);
|
||||
showMessageModal({ content: data.message });
|
||||
setTimeout(closeModal);
|
||||
emit('success');
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
310
web-vue/packages/erp/views/erp/transactionFlow/list.vue
Normal file
@@ -0,0 +1,310 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author gaoxq
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<a-button type="default" :loading="loading" @click="handleExport()">
|
||||
<Icon icon="i-ant-design:download-outlined" /> {{ t('导出') }}
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handleForm({})" v-auth="'erp:transactionFlow:edit'">
|
||||
<Icon icon="i-fluent:add-12-filled" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<InputForm @register="registerDrawer" @success="handleSuccess" />
|
||||
<FormImport @register="registerImportModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsErpTransactionFlowList">
|
||||
import { onMounted, ref, unref } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { downloadByUrl } from '@jeesite/core/utils/file/download';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicTable, BasicColumn, useTable } from '@jeesite/core/components/Table';
|
||||
import { ErpTransactionFlow, erpTransactionFlowList } from '@jeesite/erp/api/erp/transactionFlow';
|
||||
import { erpTransactionFlowDelete, erpTransactionFlowFinish, erpTransactionFlowListData } from '@jeesite/erp/api/erp/transactionFlow';
|
||||
import { useDrawer } from '@jeesite/core/components/Drawer';
|
||||
import { useModal } from '@jeesite/core/components/Modal';
|
||||
import { FormProps } from '@jeesite/core/components/Form';
|
||||
import InputForm from './form.vue';
|
||||
import FormImport from './formImport.vue';
|
||||
|
||||
const { t } = useI18n('erp.transactionFlow');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<ErpTransactionFlow>({} as ErpTransactionFlow);
|
||||
|
||||
const getTitle = {
|
||||
icon: meta.icon || 'i-ant-design:book-outlined',
|
||||
value: meta.title || t('明细信息管理'),
|
||||
};
|
||||
const loading = ref(false);
|
||||
|
||||
const searchForm: FormProps<ErpTransactionFlow> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('记录时间起'),
|
||||
field: 'createTime_gte',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('记录时间止'),
|
||||
field: 'createTime_lte',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('交易名称'),
|
||||
field: 'flowName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('交易类型'),
|
||||
field: 'transactionType',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'transaction_type',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('交易账户'),
|
||||
field: 'accountId',
|
||||
fieldLabel: 'accountName',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
selectType: 'erpAccountSelect',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('交易分类'),
|
||||
field: 'categoryId',
|
||||
fieldLabel: 'categoryName',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
selectType: 'erpCategorySelect',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('是否记账'),
|
||||
field: 'isFinish',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'is_finish',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<ErpTransactionFlow>[] = [
|
||||
{
|
||||
title: t('记录时间'),
|
||||
dataIndex: 'createTime',
|
||||
key: 'a.create_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('交易名称'),
|
||||
dataIndex: 'flowName',
|
||||
key: 'a.flow_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('交易类型'),
|
||||
dataIndex: 'transactionType',
|
||||
key: 'a.transaction_type',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'transaction_type',
|
||||
},
|
||||
{
|
||||
title: t('账户名称'),
|
||||
dataIndex: 'accountName',
|
||||
key: 'b.account_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
title: t('父级分类'),
|
||||
dataIndex: 'parentId',
|
||||
key: 'c.parent_id',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'right',
|
||||
dictType: 'parent_type',
|
||||
},
|
||||
{
|
||||
title: t('分类名称'),
|
||||
dataIndex: 'categoryName',
|
||||
key: 'c.category_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
title: t('交易金额'),
|
||||
dataIndex: 'amount',
|
||||
key: 'a.amount',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
title: t('交易时间'),
|
||||
dataIndex: 'transactionTime',
|
||||
key: 'a.transaction_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('交易备注'),
|
||||
dataIndex: 'remark',
|
||||
key: 'a.remark',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('是否记账'),
|
||||
dataIndex: 'isFinish',
|
||||
key: 'a.is_finish',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'is_finish',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateTime',
|
||||
key: 'a.update_time',
|
||||
sorter: true,
|
||||
width: 180,
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
|
||||
const actionColumn: BasicColumn<ErpTransactionFlow> = {
|
||||
width: 160,
|
||||
align: 'center',
|
||||
actions: (record: ErpTransactionFlow) => [
|
||||
{
|
||||
icon: 'i-clarity:note-edit-line',
|
||||
title: t('编辑'),
|
||||
onClick: handleForm.bind(this, { flowId: record.flowId }),
|
||||
auth: 'erp:transactionFlow:edit',
|
||||
ifShow: record.isFinish == '0'
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
title: t('删除'),
|
||||
popConfirm: {
|
||||
title: t('是否确认删除明细信息?'),
|
||||
confirm: handleDelete.bind(this, record),
|
||||
},
|
||||
auth: 'erp:transactionFlow:edit',
|
||||
ifShow: record.isFinish == '0'
|
||||
},
|
||||
{
|
||||
icon: 'simple-line-icons:check',
|
||||
color: 'success',
|
||||
title: t('记账'),
|
||||
popConfirm: {
|
||||
title: t('是否确认记账本条明细?'),
|
||||
confirm: handleFinish.bind(this, record),
|
||||
},
|
||||
auth: 'erp:transactionFlow:edit',
|
||||
ifShow: record.isFinish == '0'
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const [registerTable, { reload, getForm }] = useTable<ErpTransactionFlow>({
|
||||
api: erpTransactionFlowListData,
|
||||
beforeFetch: (params) => {
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
actionColumn: actionColumn,
|
||||
formConfig: searchForm,
|
||||
showTableSetting: true,
|
||||
useSearchForm: true,
|
||||
canResize: true,
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const res = await erpTransactionFlowList();
|
||||
record.value = (res.erpTransactionFlow || {}) as ErpTransactionFlow;
|
||||
await getForm().setFieldsValue(record.value);
|
||||
});
|
||||
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
|
||||
function handleForm(record: Recordable) {
|
||||
openDrawer(true, record);
|
||||
}
|
||||
|
||||
async function handleExport() {
|
||||
loading.value = true;
|
||||
const { ctxAdminPath } = useGlobSetting();
|
||||
await downloadByUrl({
|
||||
url: ctxAdminPath + '/erp/transactionFlow/exportData',
|
||||
params: getForm().getFieldsValue(),
|
||||
});
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
const [registerImportModal, { openModal: importModal }] = useModal();
|
||||
|
||||
function handleImport() {
|
||||
importModal(true, {});
|
||||
}
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
const params = { flowId: record.flowId };
|
||||
const res = await erpTransactionFlowDelete(params);
|
||||
showMessage(res.message);
|
||||
await handleSuccess(record);
|
||||
}
|
||||
|
||||
async function handleFinish(record: Recordable) {
|
||||
const params = { flowId: record.flowId };
|
||||
const res = await erpTransactionFlowFinish(params);
|
||||
showMessage(res.message);
|
||||
await handleSuccess(record);
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function handleSuccess(record: Recordable) {
|
||||
await reload({ record });
|
||||
}
|
||||
</script>
|
||||
15
web-vue/pnpm-lock.yaml
generated
@@ -35,6 +35,9 @@ importers:
|
||||
'@jeesite/dfm':
|
||||
specifier: workspace:*
|
||||
version: link:packages/dfm
|
||||
'@jeesite/erp':
|
||||
specifier: workspace:^
|
||||
version: link:packages/erp
|
||||
'@jeesite/test':
|
||||
specifier: workspace:*
|
||||
version: link:packages/test
|
||||
@@ -380,6 +383,16 @@ importers:
|
||||
specifier: 3.2.4
|
||||
version: 3.2.4(@types/node@24.7.2)(jiti@2.6.1)(less@4.4.2)(terser@5.44.0)(yaml@2.8.1)
|
||||
|
||||
packages/erp:
|
||||
dependencies:
|
||||
qs:
|
||||
specifier: 6.14.0
|
||||
version: 6.14.0
|
||||
devDependencies:
|
||||
'@types/qs':
|
||||
specifier: 6.9.18
|
||||
version: 6.9.18
|
||||
|
||||
packages/test: {}
|
||||
|
||||
packages/tests:
|
||||
@@ -523,7 +536,7 @@ packages:
|
||||
'@ant-design/icons-vue@7.0.1':
|
||||
resolution: {integrity: sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==}
|
||||
peerDependencies:
|
||||
vue: '>=3.0.3'
|
||||
vue: ^3.5.17
|
||||
|
||||
'@antfu/install-pkg@1.1.0':
|
||||
resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==}
|
||||
|
||||
BIN
web-vue/web/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 53 KiB |