Merge remote-tracking branch 'yudao/master'
commit
edec738466
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
'@vben/styles': patch
|
||||||
|
'@vben-core/form-ui': patch
|
||||||
|
'@vben/web-naive': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat(@core/form-ui): 新增 useVbenForm 数组编辑器 VbenFormFieldArray
|
||||||
|
|
@ -61,7 +61,7 @@ jobs:
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v3
|
uses: github/codeql-action/init@v4
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
build-mode: ${{ matrix.build-mode }}
|
build-mode: ${{ matrix.build-mode }}
|
||||||
|
|
@ -89,6 +89,6 @@ jobs:
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v3
|
uses: github/codeql-action/analyze@v4
|
||||||
with:
|
with:
|
||||||
category: '/language:${{matrix.language}}'
|
category: '/language:${{matrix.language}}'
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
# 关闭未活动的 Issues
|
# 关闭未活动的 Issues
|
||||||
- name: Close Inactive Issues
|
- name: Close Inactive Issues
|
||||||
uses: actions/stale@v9
|
uses: actions/stale@v10
|
||||||
with:
|
with:
|
||||||
days-before-stale: -1 # Issues and PR will never be flagged stale automatically.
|
days-before-stale: -1 # Issues and PR will never be flagged stale automatically.
|
||||||
stale-issue-label: needs-reproduction # Label that flags an issue as stale.
|
stale-issue-label: needs-reproduction # Label that flags an issue as stale.
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ jobs:
|
||||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: dessant/lock-threads@v5
|
- uses: dessant/lock-threads@v6
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
issue-inactive-days: '14'
|
issue-inactive-days: '14'
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Validate PR title
|
- name: Validate PR title
|
||||||
uses: amannn/action-semantic-pull-request@v5
|
uses: amannn/action-semantic-pull-request@v6
|
||||||
with:
|
with:
|
||||||
wip: true
|
wip: true
|
||||||
subjectPattern: ^(?![A-Z]).+$
|
subjectPattern: ^(?![A-Z]).+$
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ jobs:
|
||||||
if: github.repository == 'vbenjs/vue-vben-admin'
|
if: github.repository == 'vbenjs/vue-vben-admin'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9
|
- uses: actions/stale@v10
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'
|
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
22.22.0
|
24.16.0
|
||||||
|
|
|
||||||
29
README.md
29
README.md
|
|
@ -41,24 +41,24 @@
|
||||||
|
|
||||||
| 框架 | 说明 | 版本 |
|
| 框架 | 说明 | 版本 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| [Vue](https://staging-cn.vuejs.org/) | vue框架 | 3.5.30 |
|
| [Vue](https://staging-cn.vuejs.org/) | vue框架 | 3.5.35 |
|
||||||
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 8.0.0 |
|
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 8.0.10 |
|
||||||
| [Ant Design Vue](https://www.antdv.com/) | Ant Design Vue | 4.2.6 |
|
| [Ant Design Vue](https://www.antdv.com/) | Ant Design Vue | 4.2.6 |
|
||||||
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.13.5 |
|
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.14.1 |
|
||||||
| [Naive UI](https://www.naiveui.com/) | Naive UI | 2.44.1 |
|
| [Naive UI](https://www.naiveui.com/) | Naive UI | 2.44.1 |
|
||||||
| [TDesign](https://tdesign.tencent.com/) | TDesign | 1.18.5 |
|
| [TDesign](https://tdesign.tencent.com/) | TDesign | 1.20.0 |
|
||||||
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 超集 | 5.9.3 |
|
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 超集 | 6.0.3 |
|
||||||
| [pinia](https://pinia.vuejs.org/) | Vue 存储库替代 vuex5 | 3.0.4 |
|
| [pinia](https://pinia.vuejs.org/) | Vue 存储库替代 vuex5 | 3.0.4 |
|
||||||
| [vueuse](https://vueuse.org/) | 常用工具集 | 14.2.1 |
|
| [vueuse](https://vueuse.org/) | 常用工具集 | 14.3.0 |
|
||||||
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 11.3.0 |
|
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 11.4.4 |
|
||||||
| [vue-router](https://router.vuejs.org/) | Vue 路由 | 5.0.3 |
|
| [vue-router](https://router.vuejs.org/) | Vue 路由 | 5.1.0 |
|
||||||
| [Tailwind CSS](https://tailwindcss.com/) | 原子 CSS | 4.2.1 |
|
| [Tailwind CSS](https://tailwindcss.com/) | 原子 CSS | 4.3.0 |
|
||||||
| [Iconify](https://iconify.design/) | 图标组件 | 5.0.0 |
|
| [Iconify](https://iconify.design/) | 图标组件 | 5.0.1 |
|
||||||
| [Iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.449 |
|
| [Iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.481 |
|
||||||
| [TinyMCE](https://www.tiny.cloud/) | 富文本编辑器 | 7.3.0 |
|
| [TinyMCE](https://www.tiny.cloud/) | 富文本编辑器 | 7.3.0 |
|
||||||
| [Echarts](https://echarts.apache.org/) | 图表库 | 6.0.0 |
|
| [Echarts](https://echarts.apache.org/) | 图表库 | 6.1.0 |
|
||||||
| [axios](https://axios-http.com/) | http客户端 | 1.13.6 |
|
| [axios](https://axios-http.com/) | http客户端 | 1.16.1 |
|
||||||
| [dayjs](https://day.js.org/) | 日期处理库 | 1.11.20 |
|
| [dayjs](https://day.js.org/) | 日期处理库 | 1.11.21 |
|
||||||
| [vee-validate](https://vee-validate.logaretm.com/) | 表单验证 | 4.15.1 |
|
| [vee-validate](https://vee-validate.logaretm.com/) | 表单验证 | 4.15.1 |
|
||||||
| [zod](https://zod.dev/) | 数据验证 | 3.25.76 |
|
| [zod](https://zod.dev/) | 数据验证 | 3.25.76 |
|
||||||
|
|
||||||
|
|
@ -279,7 +279,6 @@
|
||||||
|
|
||||||
使用文档:<https://doc.iocoder.cn/im-preview/>
|
使用文档:<https://doc.iocoder.cn/im-preview/>
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
| 聊天界面 | 聊天管理 |
|
| 聊天界面 | 聊天管理 |
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,10 @@ export namespace CrmReceivablePlanApi {
|
||||||
returnTime: Date;
|
returnTime: Date;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
export interface PlanPageParam extends PageParam {
|
||||||
|
customerId?: number;
|
||||||
|
contractId?: number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询回款计划列表 */
|
/** 查询回款计划列表 */
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export namespace RuleSceneApi {
|
||||||
status?: number;
|
status?: number;
|
||||||
triggers?: Trigger[];
|
triggers?: Trigger[];
|
||||||
actions?: Action[];
|
actions?: Action[];
|
||||||
lastTriggeredTime?: Date;
|
lastTriggerTime?: Date;
|
||||||
createTime?: Date;
|
createTime?: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { requestClient } from '#/api/request';
|
||||||
export namespace MallTradeStatisticsApi {
|
export namespace MallTradeStatisticsApi {
|
||||||
/** 交易状况 Request */
|
/** 交易状况 Request */
|
||||||
export interface TradeTrendReqVO {
|
export interface TradeTrendReqVO {
|
||||||
times: [Date, Date];
|
times?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 交易统计 Response */
|
/** 交易统计 Response */
|
||||||
|
|
|
||||||
|
|
@ -51,5 +51,7 @@ export function deleteAutoCodeRule(id: number) {
|
||||||
|
|
||||||
/** 导出编码规则 */
|
/** 导出编码规则 */
|
||||||
export function exportAutoCodeRule(params: PageParam) {
|
export function exportAutoCodeRule(params: PageParam) {
|
||||||
return requestClient.download('/mes/md/auto-code-rule/export-excel', { params });
|
return requestClient.download('/mes/md/auto-code-rule/export-excel', {
|
||||||
|
params,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,9 @@ export namespace MesMdItemApi {
|
||||||
|
|
||||||
/** 查询物料产品分页 */
|
/** 查询物料产品分页 */
|
||||||
export function getItemPage(params: PageParam) {
|
export function getItemPage(params: PageParam) {
|
||||||
return requestClient.get<PageResult<MesMdItemApi.Item>>('/mes/md/item/page', { params });
|
return requestClient.get<PageResult<MesMdItemApi.Item>>('/mes/md/item/page', {
|
||||||
|
params,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询物料产品详情 */
|
/** 查询物料产品详情 */
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,7 @@ export function getRouteSimpleList() {
|
||||||
|
|
||||||
/** 查询工艺路线详情 */
|
/** 查询工艺路线详情 */
|
||||||
export function getRoute(id: number) {
|
export function getRoute(id: number) {
|
||||||
return requestClient.get<MesProRouteApi.Route>(
|
return requestClient.get<MesProRouteApi.Route>(`/mes/pro/route/get?id=${id}`);
|
||||||
`/mes/pro/route/get?id=${id}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 新增工艺路线 */
|
/** 新增工艺路线 */
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,16 @@ export function getDefectPage(params: PageParam) {
|
||||||
|
|
||||||
/** 查询缺陷类型精简列表 */
|
/** 查询缺陷类型精简列表 */
|
||||||
export function getDefectSimpleList() {
|
export function getDefectSimpleList() {
|
||||||
return requestClient.get<MesQcDefectApi.Defect[]>('/mes/qc/defect/simple-list');
|
return requestClient.get<MesQcDefectApi.Defect[]>(
|
||||||
|
'/mes/qc/defect/simple-list',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询缺陷类型详情 */
|
/** 查询缺陷类型详情 */
|
||||||
export function getDefect(id: number) {
|
export function getDefect(id: number) {
|
||||||
return requestClient.get<MesQcDefectApi.Defect>(`/mes/qc/defect/get?id=${id}`);
|
return requestClient.get<MesQcDefectApi.Defect>(
|
||||||
|
`/mes/qc/defect/get?id=${id}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 新增缺陷类型 */
|
/** 新增缺陷类型 */
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ export function getDefectRecord(id: number) {
|
||||||
|
|
||||||
/** 查询质检缺陷记录分页 */
|
/** 查询质检缺陷记录分页 */
|
||||||
export function getDefectRecordPage(
|
export function getDefectRecordPage(
|
||||||
params: PageParam & { lineId?: number; qcId?: number; qcType?: number; },
|
params: PageParam & { lineId?: number; qcId?: number; qcType?: number },
|
||||||
) {
|
) {
|
||||||
return requestClient.get<PageResult<MesQcDefectRecordApi.DefectRecord>>(
|
return requestClient.get<PageResult<MesQcDefectRecordApi.DefectRecord>>(
|
||||||
'/mes/qc/defect-record/page',
|
'/mes/qc/defect-record/page',
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,9 @@ export namespace MesQcIpqcApi {
|
||||||
|
|
||||||
/** 查询过程检验单分页 */
|
/** 查询过程检验单分页 */
|
||||||
export function getIpqcPage(params: PageParam) {
|
export function getIpqcPage(params: PageParam) {
|
||||||
return requestClient.get<PageResult<MesQcIpqcApi.Ipqc>>(
|
return requestClient.get<PageResult<MesQcIpqcApi.Ipqc>>('/mes/qc/ipqc/page', {
|
||||||
'/mes/qc/ipqc/page',
|
params,
|
||||||
{ params },
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询过程检验单详情 */
|
/** 查询过程检验单详情 */
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,9 @@ export namespace MesQcTemplateIndicatorApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询检测指标项分页 */
|
/** 查询检测指标项分页 */
|
||||||
export function getTemplateIndicatorPage(params: PageParam & { templateId?: number }) {
|
export function getTemplateIndicatorPage(
|
||||||
|
params: PageParam & { templateId?: number },
|
||||||
|
) {
|
||||||
return requestClient.get<
|
return requestClient.get<
|
||||||
PageResult<MesQcTemplateIndicatorApi.TemplateIndicator>
|
PageResult<MesQcTemplateIndicatorApi.TemplateIndicator>
|
||||||
>('/mes/qc/template/indicator/page', { params });
|
>('/mes/qc/template/indicator/page', { params });
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ export namespace MesQcTemplateItemApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询产品关联分页 */
|
/** 查询产品关联分页 */
|
||||||
export function getTemplateItemPage(params: PageParam & { templateId?: number }) {
|
export function getTemplateItemPage(
|
||||||
|
params: PageParam & { templateId?: number },
|
||||||
|
) {
|
||||||
return requestClient.get<PageResult<MesQcTemplateItemApi.TemplateItem>>(
|
return requestClient.get<PageResult<MesQcTemplateItemApi.TemplateItem>>(
|
||||||
'/mes/qc/template/item/page',
|
'/mes/qc/template/item/page',
|
||||||
{ params },
|
{ params },
|
||||||
|
|
|
||||||
|
|
@ -37,16 +37,12 @@ export function getArrivalNotice(id: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 新增到货通知单 */
|
/** 新增到货通知单 */
|
||||||
export function createArrivalNotice(
|
export function createArrivalNotice(data: MesWmArrivalNoticeApi.ArrivalNotice) {
|
||||||
data: MesWmArrivalNoticeApi.ArrivalNotice,
|
|
||||||
) {
|
|
||||||
return requestClient.post<number>('/mes/wm/arrival-notice/create', data);
|
return requestClient.post<number>('/mes/wm/arrival-notice/create', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改到货通知单 */
|
/** 修改到货通知单 */
|
||||||
export function updateArrivalNotice(
|
export function updateArrivalNotice(data: MesWmArrivalNoticeApi.ArrivalNotice) {
|
||||||
data: MesWmArrivalNoticeApi.ArrivalNotice,
|
|
||||||
) {
|
|
||||||
return requestClient.put('/mes/wm/arrival-notice/update', data);
|
return requestClient.put('/mes/wm/arrival-notice/update', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,7 @@ export function getArrivalNoticeLine(id: number) {
|
||||||
export function createArrivalNoticeLine(
|
export function createArrivalNoticeLine(
|
||||||
data: MesWmArrivalNoticeLineApi.ArrivalNoticeLine,
|
data: MesWmArrivalNoticeLineApi.ArrivalNoticeLine,
|
||||||
) {
|
) {
|
||||||
return requestClient.post<number>(
|
return requestClient.post<number>('/mes/wm/arrival-notice-line/create', data);
|
||||||
'/mes/wm/arrival-notice-line/create',
|
|
||||||
data,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改到货通知单行 */
|
/** 修改到货通知单行 */
|
||||||
|
|
|
||||||
|
|
@ -73,9 +73,12 @@ export function getBatchPage(params: MesWmBatchApi.PageParams) {
|
||||||
|
|
||||||
/** 批次向前追溯 */
|
/** 批次向前追溯 */
|
||||||
export function getForwardBatchList(code: string) {
|
export function getForwardBatchList(code: string) {
|
||||||
return requestClient.get<MesWmBatchApi.Batch[]>('/mes/wm/batch/forward-list', {
|
return requestClient.get<MesWmBatchApi.Batch[]>(
|
||||||
params: { code },
|
'/mes/wm/batch/forward-list',
|
||||||
});
|
{
|
||||||
|
params: { code },
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 批次向后追溯 */
|
/** 批次向后追溯 */
|
||||||
|
|
|
||||||
|
|
@ -66,5 +66,7 @@ export function cancelMiscReceipt(id: number) {
|
||||||
|
|
||||||
/** 导出杂项入库单 */
|
/** 导出杂项入库单 */
|
||||||
export function exportMiscReceipt(params: any) {
|
export function exportMiscReceipt(params: any) {
|
||||||
return requestClient.download('/mes/wm/misc-receipt/export-excel', { params });
|
return requestClient.download('/mes/wm/misc-receipt/export-excel', {
|
||||||
|
params,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,10 @@ export namespace MesWmOutsourceIssueDetailApi {
|
||||||
|
|
||||||
/** 查询外协发料单明细列表 */
|
/** 查询外协发料单明细列表 */
|
||||||
export function getOutsourceIssueDetailListByLineId(lineId: number) {
|
export function getOutsourceIssueDetailListByLineId(lineId: number) {
|
||||||
return requestClient.get<
|
return requestClient.get<MesWmOutsourceIssueDetailApi.OutsourceIssueDetail[]>(
|
||||||
MesWmOutsourceIssueDetailApi.OutsourceIssueDetail[]
|
'/mes/wm/outsource-issue-detail/list-by-line',
|
||||||
>('/mes/wm/outsource-issue-detail/list-by-line', { params: { lineId } });
|
{ params: { lineId } },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询外协发料单明细详情 */
|
/** 查询外协发料单明细详情 */
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,9 @@ export namespace MesWmOutsourceReceiptApi {
|
||||||
|
|
||||||
/** 查询外协入库单分页 */
|
/** 查询外协入库单分页 */
|
||||||
export function getOutsourceReceiptPage(params: PageParam) {
|
export function getOutsourceReceiptPage(params: PageParam) {
|
||||||
return requestClient.get<PageResult<MesWmOutsourceReceiptApi.OutsourceReceipt>>(
|
return requestClient.get<
|
||||||
'/mes/wm/outsource-receipt/page',
|
PageResult<MesWmOutsourceReceiptApi.OutsourceReceipt>
|
||||||
{ params },
|
>('/mes/wm/outsource-receipt/page', { params });
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询外协入库单详情 */
|
/** 查询外协入库单详情 */
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,10 @@ export function getProductIssueDetail(id: number) {
|
||||||
export function createProductIssueDetail(
|
export function createProductIssueDetail(
|
||||||
data: MesWmProductIssueDetailApi.ProductIssueDetail,
|
data: MesWmProductIssueDetailApi.ProductIssueDetail,
|
||||||
) {
|
) {
|
||||||
return requestClient.post<number>('/mes/wm/product-issue-detail/create', data);
|
return requestClient.post<number>(
|
||||||
|
'/mes/wm/product-issue-detail/create',
|
||||||
|
data,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改领料出库明细 */
|
/** 修改领料出库明细 */
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,9 @@ export namespace MesWmProductIssueLineApi {
|
||||||
|
|
||||||
/** 查询领料出库单行分页 */
|
/** 查询领料出库单行分页 */
|
||||||
export function getProductIssueLinePage(params: PageParam) {
|
export function getProductIssueLinePage(params: PageParam) {
|
||||||
return requestClient.get<PageResult<MesWmProductIssueLineApi.ProductIssueLine>>(
|
return requestClient.get<
|
||||||
'/mes/wm/product-issue-line/page',
|
PageResult<MesWmProductIssueLineApi.ProductIssueLine>
|
||||||
{ params },
|
>('/mes/wm/product-issue-line/page', { params });
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询领料出库单行详情 */
|
/** 查询领料出库单行详情 */
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,10 @@ export function getProductSalesDetail(id: number) {
|
||||||
export function createProductSalesDetail(
|
export function createProductSalesDetail(
|
||||||
data: MesWmProductSalesDetailApi.ProductSalesDetail,
|
data: MesWmProductSalesDetailApi.ProductSalesDetail,
|
||||||
) {
|
) {
|
||||||
return requestClient.post<number>('/mes/wm/product-sales-detail/create', data);
|
return requestClient.post<number>(
|
||||||
|
'/mes/wm/product-sales-detail/create',
|
||||||
|
data,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改销售出库明细 */
|
/** 修改销售出库明细 */
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,10 @@ export function getReturnVendorDetail(id: number) {
|
||||||
export function createReturnVendorDetail(
|
export function createReturnVendorDetail(
|
||||||
data: MesWmReturnVendorDetailApi.ReturnVendorDetail,
|
data: MesWmReturnVendorDetailApi.ReturnVendorDetail,
|
||||||
) {
|
) {
|
||||||
return requestClient.post<number>('/mes/wm/return-vendor-detail/create', data);
|
return requestClient.post<number>(
|
||||||
|
'/mes/wm/return-vendor-detail/create',
|
||||||
|
data,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改供应商退货明细 */
|
/** 修改供应商退货明细 */
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,9 @@ export namespace MesWmReturnVendorLineApi {
|
||||||
|
|
||||||
/** 查询供应商退货单行分页 */
|
/** 查询供应商退货单行分页 */
|
||||||
export function getReturnVendorLinePage(params: PageParam) {
|
export function getReturnVendorLinePage(params: PageParam) {
|
||||||
return requestClient.get<PageResult<MesWmReturnVendorLineApi.ReturnVendorLine>>(
|
return requestClient.get<
|
||||||
'/mes/wm/return-vendor-line/page',
|
PageResult<MesWmReturnVendorLineApi.ReturnVendorLine>
|
||||||
{ params },
|
>('/mes/wm/return-vendor-line/page', { params });
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询供应商退货单行详情 */
|
/** 查询供应商退货单行详情 */
|
||||||
|
|
|
||||||
|
|
@ -60,5 +60,7 @@ export function updateStockTakingResult(
|
||||||
|
|
||||||
/** 删除盘点结果 */
|
/** 删除盘点结果 */
|
||||||
export function deleteStockTakingResult(id: number) {
|
export function deleteStockTakingResult(id: number) {
|
||||||
return requestClient.delete(`/mes/wm/stocktaking-task-result/delete?id=${id}`);
|
return requestClient.delete(
|
||||||
|
`/mes/wm/stocktaking-task-result/delete?id=${id}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
title: '库区设置',
|
title: '库区设置',
|
||||||
activePath: '/mes/wm/warehouse',
|
activePath: '/mes/wm/warehouse',
|
||||||
},
|
},
|
||||||
component: () =>
|
component: () => import('#/views/mes/wm/warehouse/location/index.vue'),
|
||||||
import('#/views/mes/wm/warehouse/location/index.vue'),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'wm/warehouse/area',
|
path: 'wm/warehouse/area',
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,9 @@ async function handleStatusChange(
|
||||||
row: AiKnowledgeDocumentApi.KnowledgeDocument,
|
row: AiKnowledgeDocumentApi.KnowledgeDocument,
|
||||||
): Promise<boolean | undefined> {
|
): Promise<boolean | undefined> {
|
||||||
try {
|
try {
|
||||||
await confirm(`你要将${row.name}的状态切换为【${getDictLabel(DICT_TYPE.COMMON_STATUS, newStatus)}】吗?`);
|
await confirm(
|
||||||
|
`你要将${row.name}的状态切换为【${getDictLabel(DICT_TYPE.COMMON_STATUS, newStatus)}】吗?`,
|
||||||
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,9 @@ async function handleStatusChange(
|
||||||
row: AiKnowledgeSegmentApi.KnowledgeSegment,
|
row: AiKnowledgeSegmentApi.KnowledgeSegment,
|
||||||
): Promise<boolean | undefined> {
|
): Promise<boolean | undefined> {
|
||||||
try {
|
try {
|
||||||
await confirm(`你要将片段 ${row.id} 的状态切换为【${getDictLabel(DICT_TYPE.COMMON_STATUS, newStatus)}】吗?`);
|
await confirm(
|
||||||
|
`你要将片段 ${row.id} 的状态切换为【${getDictLabel(DICT_TYPE.COMMON_STATUS, newStatus)}】吗?`,
|
||||||
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ const resetTaskForm = () => {
|
||||||
|
|
||||||
// 改用通过extensionElements来存储数据
|
// 改用通过extensionElements来存储数据
|
||||||
|
|
||||||
// if (businessObject.candidateStrategy != undefined) {
|
// if (businessObject.candidateStrategy !== undefined) {
|
||||||
// userTaskForm.value.candidateStrategy = parseInt(
|
// userTaskForm.value.candidateStrategy = parseInt(
|
||||||
// businessObject.candidateStrategy,
|
// businessObject.candidateStrategy,
|
||||||
// ) as any;
|
// ) as any;
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,9 @@ function createFileLinkHtml(file: unknown) {
|
||||||
linkEl.setAttribute('href', String(url));
|
linkEl.setAttribute('href', String(url));
|
||||||
linkEl.setAttribute('target', '_blank');
|
linkEl.setAttribute('target', '_blank');
|
||||||
linkEl.setAttribute('rel', 'noopener noreferrer');
|
linkEl.setAttribute('rel', 'noopener noreferrer');
|
||||||
const fallbackName = String(url).slice(Math.max(0, String(url).lastIndexOf('/') + 1)) || String(url);
|
const fallbackName =
|
||||||
|
String(url).slice(Math.max(0, String(url).lastIndexOf('/') + 1)) ||
|
||||||
|
String(url);
|
||||||
const recordName = record ? getRecordValue(record, 'name') : undefined;
|
const recordName = record ? getRecordValue(record, 'name') : undefined;
|
||||||
linkEl.textContent = recordName ? String(recordName) : fallbackName;
|
linkEl.textContent = recordName ? String(recordName) : fallbackName;
|
||||||
return linkEl.outerHTML;
|
return linkEl.outerHTML;
|
||||||
|
|
@ -247,16 +249,14 @@ function renderFileListHtml(value: unknown) {
|
||||||
.join('<br/>');
|
.join('<br/>');
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapValuesWithOptions(
|
function mapValuesWithOptions(value: unknown, options: FormFieldOption[] = []) {
|
||||||
value: unknown,
|
|
||||||
options: FormFieldOption[] = [],
|
|
||||||
) {
|
|
||||||
const values = toValueArray(value);
|
const values = toValueArray(value);
|
||||||
const labels = values
|
const labels = values
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
const matched = options.find(
|
const matched = options.find(
|
||||||
(option) =>
|
(option) =>
|
||||||
option?.value === item || String(option?.value ?? '') === String(item),
|
option?.value === item ||
|
||||||
|
String(option?.value ?? '') === String(item),
|
||||||
);
|
);
|
||||||
return escapeHtml(matched?.label ?? String(item));
|
return escapeHtml(matched?.label ?? String(item));
|
||||||
})
|
})
|
||||||
|
|
@ -300,9 +300,15 @@ function mapValueWithLabelMap(
|
||||||
* @returns 打印展示时使用的区域、部门、用户名称映射
|
* @returns 打印展示时使用的区域、部门、用户名称映射
|
||||||
*/
|
*/
|
||||||
async function loadPrintLookupMaps(formFieldsObj: FormFieldRule[]) {
|
async function loadPrintLookupMaps(formFieldsObj: FormFieldRule[]) {
|
||||||
const hasAreaSelect = formFieldsObj.some((item) => item.type === 'AreaSelect');
|
const hasAreaSelect = formFieldsObj.some(
|
||||||
const hasUserSelect = formFieldsObj.some((item) => item.type === 'UserSelect');
|
(item) => item.type === 'AreaSelect',
|
||||||
const hasDeptSelect = formFieldsObj.some((item) => item.type === 'DeptSelect');
|
);
|
||||||
|
const hasUserSelect = formFieldsObj.some(
|
||||||
|
(item) => item.type === 'UserSelect',
|
||||||
|
);
|
||||||
|
const hasDeptSelect = formFieldsObj.some(
|
||||||
|
(item) => item.type === 'DeptSelect',
|
||||||
|
);
|
||||||
|
|
||||||
const [areaList, userList, deptList] = await Promise.all([
|
const [areaList, userList, deptList] = await Promise.all([
|
||||||
hasAreaSelect ? getAreaTree() : Promise.resolve([]),
|
hasAreaSelect ? getAreaTree() : Promise.resolve([]),
|
||||||
|
|
@ -335,7 +341,7 @@ function formatPrintField(
|
||||||
rule: FormFieldRule,
|
rule: FormFieldRule,
|
||||||
value: unknown,
|
value: unknown,
|
||||||
lookupMaps: PrintLookupMaps,
|
lookupMaps: PrintLookupMaps,
|
||||||
){
|
) {
|
||||||
const type = String(rule.type ?? '');
|
const type = String(rule.type ?? '');
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
@ -387,8 +393,9 @@ function formatPrintField(
|
||||||
} as const;
|
} as const;
|
||||||
const rawValueType = String(getRuleProp(rule, 'valueType') ?? '');
|
const rawValueType = String(getRuleProp(rule, 'valueType') ?? '');
|
||||||
const valueType =
|
const valueType =
|
||||||
(valueTypeMap as Record<string, 'boolean' | 'number' | 'string'>)[rawValueType] ??
|
(valueTypeMap as Record<string, 'boolean' | 'number' | 'string'>)[
|
||||||
'string';
|
rawValueType
|
||||||
|
] ?? 'string';
|
||||||
const options = getDictOptions(dictType, valueType);
|
const options = getDictOptions(dictType, valueType);
|
||||||
return mapValuesWithOptions(value, options);
|
return mapValuesWithOptions(value, options);
|
||||||
}
|
}
|
||||||
|
|
@ -402,10 +409,9 @@ function formatPrintField(
|
||||||
}
|
}
|
||||||
case 'IframeComponent': {
|
case 'IframeComponent': {
|
||||||
const propsObj = rule.props;
|
const propsObj = rule.props;
|
||||||
const propsUrl =
|
const propsUrl = isPrintableRecord(propsObj)
|
||||||
isPrintableRecord(propsObj)
|
? String(getRecordValue(propsObj, 'url') ?? '')
|
||||||
? String(getRecordValue(propsObj, 'url') ?? '')
|
: '';
|
||||||
: '';
|
|
||||||
const iframeUrl = isEmptyValue(value) ? propsUrl : String(value ?? '');
|
const iframeUrl = isEmptyValue(value) ? propsUrl : String(value ?? '');
|
||||||
return iframeUrl ? createFileLinkHtml(iframeUrl) : '';
|
return iframeUrl ? createFileLinkHtml(iframeUrl) : '';
|
||||||
}
|
}
|
||||||
|
|
@ -446,7 +452,9 @@ function initPrintDataMap() {
|
||||||
printDataMap.value.startUserDept =
|
printDataMap.value.startUserDept =
|
||||||
printData.value.processInstance.startUser?.deptName || '';
|
printData.value.processInstance.startUser?.deptName || '';
|
||||||
printDataMap.value.processName = printData.value.processInstance.name;
|
printDataMap.value.processName = printData.value.processInstance.name;
|
||||||
printDataMap.value.processNum = String(printData.value.processInstance.id ?? '');
|
printDataMap.value.processNum = String(
|
||||||
|
printData.value.processInstance.id ?? '',
|
||||||
|
);
|
||||||
printDataMap.value.startTime = formatDate(
|
printDataMap.value.startTime = formatDate(
|
||||||
printData.value.processInstance.startTime,
|
printData.value.processInstance.startTime,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,9 @@ async function handleDeleteContactBusinessList() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await confirm(`确定要将${checkedRows.value.map((item) => item.name).join(',')}解除关联吗?`);
|
await confirm(
|
||||||
|
`确定要将${checkedRows.value.map((item) => item.name).join(',')}解除关联吗?`,
|
||||||
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,9 @@ async function handleDeleteContactBusinessList() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await confirm(`确定要将${checkedRows.value.map((item) => item.name).join(',')}解除关联吗?`);
|
await confirm(
|
||||||
|
`确定要将${checkedRows.value.map((item) => item.name).join(',')}解除关联吗?`,
|
||||||
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,9 @@ async function handlePutPool(): Promise<boolean | undefined> {
|
||||||
async function handleUpdateDealStatus(): Promise<boolean | undefined> {
|
async function handleUpdateDealStatus(): Promise<boolean | undefined> {
|
||||||
const dealStatus = !customer.value.dealStatus;
|
const dealStatus = !customer.value.dealStatus;
|
||||||
try {
|
try {
|
||||||
await confirm(`确定更新成交状态为【${dealStatus ? '已成交' : '未成交'}】吗?`);
|
await confirm(
|
||||||
|
`确定更新成交状态为【${dealStatus ? '已成交' : '未成交'}】吗?`,
|
||||||
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,9 @@ async function handleDelete() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await confirm(`你要将${checkedRows.value.map((item) => item.nickname).join(',')}移出团队吗?`);
|
await confirm(
|
||||||
|
`你要将${checkedRows.value.map((item) => item.nickname).join(',')}移出团队吗?`,
|
||||||
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,12 +57,19 @@ export function useFormSchema(): VbenFormSchema[] {
|
||||||
label: '客户名称',
|
label: '客户名称',
|
||||||
component: 'ApiSelect',
|
component: 'ApiSelect',
|
||||||
rules: 'required',
|
rules: 'required',
|
||||||
componentProps: {
|
componentProps: (_values, form) => ({
|
||||||
api: getCustomerSimpleList,
|
api: getCustomerSimpleList,
|
||||||
labelField: 'name',
|
labelField: 'name',
|
||||||
valueField: 'id',
|
valueField: 'id',
|
||||||
placeholder: '请选择客户',
|
placeholder: '请选择客户',
|
||||||
},
|
onChange: () => {
|
||||||
|
form.setFieldValue('contractId', undefined);
|
||||||
|
form.setFieldValue('planId', undefined);
|
||||||
|
form.setFieldValue('price', undefined);
|
||||||
|
form.setFieldValue('returnTime', undefined);
|
||||||
|
form.setFieldValue('returnType', undefined);
|
||||||
|
},
|
||||||
|
}),
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['id'],
|
triggerFields: ['id'],
|
||||||
disabled: (values) => values.id,
|
disabled: (values) => values.id,
|
||||||
|
|
@ -76,21 +83,33 @@ export function useFormSchema(): VbenFormSchema[] {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['customerId'],
|
triggerFields: ['customerId'],
|
||||||
disabled: (values) => !values.customerId || values.id,
|
disabled: (values) => !values.customerId || values.id,
|
||||||
async componentProps(values) {
|
async componentProps(values, form) {
|
||||||
if (values.customerId) {
|
if (!values.customerId) {
|
||||||
if (!values.id) {
|
|
||||||
// 特殊:只有在【新增】时,才清空合同编号
|
|
||||||
values.contractId = undefined;
|
|
||||||
}
|
|
||||||
const contracts = await getContractSimpleList(values.customerId);
|
|
||||||
return {
|
return {
|
||||||
options: contracts.map((item) => ({
|
options: [],
|
||||||
label: item.name,
|
placeholder: '请选择客户',
|
||||||
value: item.id,
|
};
|
||||||
})),
|
|
||||||
placeholder: '请选择合同',
|
|
||||||
} as any;
|
|
||||||
}
|
}
|
||||||
|
const contracts = await getContractSimpleList(values.customerId);
|
||||||
|
return {
|
||||||
|
options: contracts.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
})),
|
||||||
|
placeholder: '请选择合同',
|
||||||
|
onChange: (value: number) => {
|
||||||
|
form.setFieldValue('planId', undefined);
|
||||||
|
form.setFieldValue('returnTime', undefined);
|
||||||
|
form.setFieldValue('returnType', undefined);
|
||||||
|
const contract = contracts.find((item) => item.id === value);
|
||||||
|
form.setFieldValue(
|
||||||
|
'price',
|
||||||
|
contract
|
||||||
|
? contract.totalPrice - contract.totalReceivablePrice
|
||||||
|
: undefined,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
} as any;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -101,28 +120,38 @@ export function useFormSchema(): VbenFormSchema[] {
|
||||||
rules: 'required',
|
rules: 'required',
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['contractId'],
|
triggerFields: ['contractId'],
|
||||||
disabled: (values) => !values.contractId,
|
disabled: (values) => !values.contractId || values.id,
|
||||||
async componentProps(values) {
|
async componentProps(values, form) {
|
||||||
if (values.contractId) {
|
if (!values.contractId) {
|
||||||
values.planId = undefined;
|
|
||||||
const plans = await getReceivablePlanSimpleList(
|
|
||||||
values.customerId,
|
|
||||||
values.contractId,
|
|
||||||
);
|
|
||||||
return {
|
return {
|
||||||
options: plans.map((item) => ({
|
options: [],
|
||||||
label: item.period,
|
placeholder: '请选择合同',
|
||||||
value: item.id,
|
};
|
||||||
})),
|
|
||||||
placeholder: '请选择回款期数',
|
|
||||||
onChange: async (value: any) => {
|
|
||||||
const plan = await getReceivablePlan(value);
|
|
||||||
values.returnTime = plan?.returnTime;
|
|
||||||
values.price = plan?.price;
|
|
||||||
values.returnType = plan?.returnType;
|
|
||||||
},
|
|
||||||
} as any;
|
|
||||||
}
|
}
|
||||||
|
const plans = await getReceivablePlanSimpleList(
|
||||||
|
values.customerId,
|
||||||
|
values.contractId,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
options: plans.map((item) => ({
|
||||||
|
disabled: !!item.receivableId,
|
||||||
|
label: `第 ${item.period} 期`,
|
||||||
|
value: item.id,
|
||||||
|
})),
|
||||||
|
placeholder: '请选择回款期数',
|
||||||
|
onChange: async (value: any) => {
|
||||||
|
if (!value) {
|
||||||
|
form.setFieldValue('returnTime', undefined);
|
||||||
|
form.setFieldValue('price', undefined);
|
||||||
|
form.setFieldValue('returnType', undefined);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const plan = await getReceivablePlan(value);
|
||||||
|
form.setFieldValue('returnTime', plan?.returnTime);
|
||||||
|
form.setFieldValue('price', plan?.price);
|
||||||
|
form.setFieldValue('returnType', plan?.returnType);
|
||||||
|
},
|
||||||
|
} as any;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { useVbenForm, useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { getContractSimpleList } from '#/api/crm/contract';
|
||||||
import {
|
import {
|
||||||
createReceivable,
|
createReceivable,
|
||||||
getReceivable,
|
getReceivable,
|
||||||
|
|
@ -16,8 +17,20 @@ import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useFormSchema } from '../data';
|
import { useFormSchema } from '../data';
|
||||||
|
|
||||||
|
type ReceivablePrefillData = Partial<
|
||||||
|
Pick<
|
||||||
|
CrmReceivableApi.Receivable,
|
||||||
|
'contractId' | 'customerId' | 'price' | 'returnType'
|
||||||
|
>
|
||||||
|
> & { id?: number };
|
||||||
|
|
||||||
|
type ReceivableFormModalData = ReceivablePrefillData & {
|
||||||
|
plan?: ReceivablePrefillData;
|
||||||
|
receivable?: Pick<CrmReceivableApi.Receivable, 'id'>;
|
||||||
|
};
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
const emit = defineEmits(['success']);
|
||||||
const formData = ref<CrmReceivableApi.Receivable>();
|
const formData = ref<Partial<CrmReceivableApi.Receivable>>();
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
return formData.value?.id
|
return formData.value?.id
|
||||||
? $t('ui.actionTitle.edit', ['回款'])
|
? $t('ui.actionTitle.edit', ['回款'])
|
||||||
|
|
@ -36,6 +49,32 @@ const [Form, formApi] = useVbenForm({
|
||||||
showDefaultActions: false,
|
showDefaultActions: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/** 构建新增回款的预填表单 */
|
||||||
|
async function buildCreateFormData(
|
||||||
|
plan: ReceivablePrefillData,
|
||||||
|
): Promise<Partial<CrmReceivableApi.Receivable>> {
|
||||||
|
const values: Partial<CrmReceivableApi.Receivable> = {
|
||||||
|
contractId: plan?.contractId,
|
||||||
|
customerId: plan?.customerId,
|
||||||
|
};
|
||||||
|
// 从回款计划创建时,直接继承计划的期数、金额和回款方式
|
||||||
|
if (plan?.id) {
|
||||||
|
values.planId = plan.id;
|
||||||
|
values.price = plan.price;
|
||||||
|
values.returnType = plan.returnType;
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
// 从客户/合同详情创建时,没有计划期数,按合同剩余应回款金额预填
|
||||||
|
if (values.customerId && values.contractId) {
|
||||||
|
const contracts = await getContractSimpleList(values.customerId);
|
||||||
|
const contract = contracts.find((item) => item.id === values.contractId);
|
||||||
|
if (contract) {
|
||||||
|
values.price = contract.totalPrice - contract.totalReceivablePrice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
async onConfirm() {
|
async onConfirm() {
|
||||||
const { valid } = await formApi.validate();
|
const { valid } = await formApi.validate();
|
||||||
|
|
@ -63,31 +102,26 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 加载数据
|
// 加载数据
|
||||||
const data = modalApi.getData();
|
formData.value = undefined;
|
||||||
|
await formApi.resetForm();
|
||||||
|
const data = modalApi.getData() as null | ReceivableFormModalData;
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { receivable, plan } = data;
|
const { receivable } = data;
|
||||||
|
const plan =
|
||||||
|
data.plan ?? (data.customerId || data.contractId ? data : undefined);
|
||||||
modalApi.lock();
|
modalApi.lock();
|
||||||
try {
|
try {
|
||||||
if (receivable) {
|
if (receivable?.id) {
|
||||||
formData.value = await getReceivable(receivable.id!);
|
formData.value = await getReceivable(receivable.id!);
|
||||||
} else if (plan) {
|
} else if (plan) {
|
||||||
formData.value = plan.id
|
formData.value = await buildCreateFormData(plan);
|
||||||
? {
|
}
|
||||||
planId: plan.id,
|
if (formData.value) {
|
||||||
price: plan.price,
|
// 设置到 values
|
||||||
returnType: plan.returnType,
|
await formApi.setValues(formData.value as any);
|
||||||
customerId: plan.customerId,
|
|
||||||
contractId: plan.contractId,
|
|
||||||
}
|
|
||||||
: ({
|
|
||||||
customerId: plan.customerId,
|
|
||||||
contractId: plan.contractId,
|
|
||||||
} as any);
|
|
||||||
}
|
}
|
||||||
// 设置到 values
|
|
||||||
await formApi.setValues(formData.value as any);
|
|
||||||
} finally {
|
} finally {
|
||||||
modalApi.unlock();
|
modalApi.unlock();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,7 @@ function navTo(nav: WorkbenchProjectItem | WorkbenchQuickNavItem) {
|
||||||
<template #description> 今日晴,20℃ - 32℃! </template>
|
<template #description> 今日晴,20℃ - 32℃! </template>
|
||||||
</WorkbenchHeader>
|
</WorkbenchHeader>
|
||||||
|
|
||||||
<div class="mt-5 flex flex-col lg:flex-row">
|
<div class="flex flex-col lg:flex-row">
|
||||||
<div class="mr-4 w-full lg:w-3/5">
|
<div class="mr-4 w-full lg:w-3/5">
|
||||||
<WorkbenchProject :items="projectItems" title="项目" @click="navTo" />
|
<WorkbenchProject :items="projectItems" title="项目" @click="navTo" />
|
||||||
<WorkbenchTrends :items="trendItems" class="mt-5" title="最新动态" />
|
<WorkbenchTrends :items="trendItems" class="mt-5" title="最新动态" />
|
||||||
|
|
@ -246,7 +246,7 @@ function navTo(nav: WorkbenchProjectItem | WorkbenchQuickNavItem) {
|
||||||
<div class="w-full lg:w-2/5">
|
<div class="w-full lg:w-2/5">
|
||||||
<WorkbenchQuickNav
|
<WorkbenchQuickNav
|
||||||
:items="quickNavItems"
|
:items="quickNavItems"
|
||||||
class="mt-5 lg:mt-0"
|
class="lg:mt-0"
|
||||||
title="快捷导航"
|
title="快捷导航"
|
||||||
@click="navTo"
|
@click="navTo"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
<Modal
|
<Modal
|
||||||
:title="getTitle"
|
:title="getTitle"
|
||||||
class="w-3/4"
|
class="w-3/4"
|
||||||
|
:close-on-click-modal="false"
|
||||||
:show-confirm-button="formType !== 'detail'"
|
:show-confirm-button="formType !== 'detail'"
|
||||||
>
|
>
|
||||||
<Form class="mx-3">
|
<Form class="mx-3">
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
},
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: usePurchaseInGridColumns(),
|
columns: usePurchaseInGridColumns(),
|
||||||
height: 'auto',
|
height: 520,
|
||||||
keepSource: true,
|
keepSource: true,
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
|
|
@ -95,14 +95,12 @@ defineExpose({ open: openModal });
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal
|
<Modal
|
||||||
class="!w-[50vw]"
|
|
||||||
v-model:open="open"
|
v-model:open="open"
|
||||||
title="选择采购入库单"
|
title="选择采购入库单"
|
||||||
@ok="handleOk"
|
width="80%"
|
||||||
|
@cancel.stop="open = false"
|
||||||
|
@ok.stop="handleOk"
|
||||||
>
|
>
|
||||||
<Grid
|
<Grid table-title="采购入库单列表(仅展示可付款的单据)" />
|
||||||
class="max-h-[600px]"
|
|
||||||
table-title="采购入库单列表(仅展示可付款的单据)"
|
|
||||||
/>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
},
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useSaleReturnGridColumns(),
|
columns: useSaleReturnGridColumns(),
|
||||||
height: 'auto',
|
height: 520,
|
||||||
keepSource: true,
|
keepSource: true,
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
|
|
@ -99,14 +99,12 @@ defineExpose({ open: openModal });
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal
|
<Modal
|
||||||
class="!w-[50vw]"
|
|
||||||
v-model:open="open"
|
v-model:open="open"
|
||||||
title="选择采购退货单"
|
title="选择采购退货单"
|
||||||
@ok="handleOk"
|
width="80%"
|
||||||
|
@cancel.stop="open = false"
|
||||||
|
@ok.stop="handleOk"
|
||||||
>
|
>
|
||||||
<Grid
|
<Grid table-title="采购退货单列表(仅展示需退款的单据)" />
|
||||||
class="max-h-[600px]"
|
|
||||||
table-title="采购退货单列表(仅展示需退款的单据)"
|
|
||||||
/>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
<Modal
|
<Modal
|
||||||
:title="getTitle"
|
:title="getTitle"
|
||||||
class="w-3/4"
|
class="w-3/4"
|
||||||
|
:close-on-click-modal="false"
|
||||||
:show-confirm-button="formType !== 'detail'"
|
:show-confirm-button="formType !== 'detail'"
|
||||||
>
|
>
|
||||||
<Form class="mx-3">
|
<Form class="mx-3">
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
},
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useSaleOutGridColumns(),
|
columns: useSaleOutGridColumns(),
|
||||||
height: 'auto',
|
height: 520,
|
||||||
keepSource: true,
|
keepSource: true,
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
|
|
@ -91,14 +91,12 @@ defineExpose({ open: openModal });
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal
|
<Modal
|
||||||
class="!w-[50vw]"
|
|
||||||
v-model:open="open"
|
v-model:open="open"
|
||||||
title="选择销售出库单"
|
title="选择销售出库单"
|
||||||
@ok="handleOk"
|
width="80%"
|
||||||
|
@cancel.stop="open = false"
|
||||||
|
@ok.stop="handleOk"
|
||||||
>
|
>
|
||||||
<Grid
|
<Grid table-title="销售出库单列表(仅展示可收款的单据)" />
|
||||||
class="max-h-[600px]"
|
|
||||||
table-title="销售出库单列表(仅展示可收款的单据)"
|
|
||||||
/>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
},
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useSaleReturnGridColumns(),
|
columns: useSaleReturnGridColumns(),
|
||||||
height: 'auto',
|
height: 520,
|
||||||
keepSource: true,
|
keepSource: true,
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
|
|
@ -95,14 +95,12 @@ defineExpose({ open: openModal });
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal
|
<Modal
|
||||||
class="!w-[50vw]"
|
|
||||||
v-model:open="open"
|
v-model:open="open"
|
||||||
title="选择销售退货单"
|
title="选择销售退货单"
|
||||||
@ok="handleOk"
|
width="80%"
|
||||||
|
@cancel.stop="open = false"
|
||||||
|
@ok.stop="handleOk"
|
||||||
>
|
>
|
||||||
<Grid
|
<Grid table-title="销售退货单列表(仅展示可退款的单据)" />
|
||||||
class="max-h-[600px]"
|
|
||||||
table-title="销售退货单列表(仅展示可退款的单据)"
|
|
||||||
/>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
<Modal
|
<Modal
|
||||||
:title="getTitle"
|
:title="getTitle"
|
||||||
class="w-3/4"
|
class="w-3/4"
|
||||||
|
:close-on-click-modal="false"
|
||||||
:show-confirm-button="formType !== 'detail'"
|
:show-confirm-button="formType !== 'detail'"
|
||||||
>
|
>
|
||||||
<Form class="mx-3">
|
<Form class="mx-3">
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const [Grid] = useVbenVxeGrid({
|
||||||
},
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useOrderGridColumns(),
|
columns: useOrderGridColumns(),
|
||||||
height: 'auto',
|
height: 520,
|
||||||
keepSource: true,
|
keepSource: true,
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
|
|
@ -108,12 +108,13 @@ function handleOk() {
|
||||||
</template>
|
</template>
|
||||||
</Input>
|
</Input>
|
||||||
<Modal
|
<Modal
|
||||||
class="!w-[50vw]"
|
|
||||||
v-model:open="open"
|
v-model:open="open"
|
||||||
title="选择关联订单"
|
title="选择关联订单"
|
||||||
@ok="handleOk"
|
width="80%"
|
||||||
|
@cancel.stop="open = false"
|
||||||
|
@ok.stop="handleOk"
|
||||||
>
|
>
|
||||||
<Grid class="max-h-[600px]" table-title="采购订单列表(仅展示可退货)" />
|
<Grid table-title="采购订单列表(仅展示可退货)" />
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
<Modal
|
<Modal
|
||||||
:title="getTitle"
|
:title="getTitle"
|
||||||
class="w-3/4"
|
class="w-3/4"
|
||||||
|
:close-on-click-modal="false"
|
||||||
:show-confirm-button="formType !== 'detail'"
|
:show-confirm-button="formType !== 'detail'"
|
||||||
>
|
>
|
||||||
<Form class="mx-3">
|
<Form class="mx-3">
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const [Grid] = useVbenVxeGrid({
|
||||||
},
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useOrderGridColumns(),
|
columns: useOrderGridColumns(),
|
||||||
height: 'auto',
|
height: 520,
|
||||||
keepSource: true,
|
keepSource: true,
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
|
|
@ -108,12 +108,13 @@ function handleOk() {
|
||||||
</template>
|
</template>
|
||||||
</Input>
|
</Input>
|
||||||
<Modal
|
<Modal
|
||||||
class="!w-[50vw]"
|
|
||||||
v-model:open="open"
|
v-model:open="open"
|
||||||
title="选择关联订单"
|
title="选择关联订单"
|
||||||
@ok="handleOk"
|
width="80%"
|
||||||
|
@cancel.stop="open = false"
|
||||||
|
@ok.stop="handleOk"
|
||||||
>
|
>
|
||||||
<Grid class="max-h-[600px]" table-title="采购订单列表(仅展示可退货)" />
|
<Grid table-title="采购订单列表(仅展示可退货)" />
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
<Modal
|
<Modal
|
||||||
:title="getTitle"
|
:title="getTitle"
|
||||||
class="w-3/4"
|
class="w-3/4"
|
||||||
|
:close-on-click-modal="false"
|
||||||
:show-confirm-button="formType !== 'detail'"
|
:show-confirm-button="formType !== 'detail'"
|
||||||
>
|
>
|
||||||
<Form class="mx-3">
|
<Form class="mx-3">
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const [Grid] = useVbenVxeGrid({
|
||||||
},
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useOrderGridColumns(),
|
columns: useOrderGridColumns(),
|
||||||
height: 'auto',
|
height: 520,
|
||||||
keepSource: true,
|
keepSource: true,
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
|
|
@ -108,12 +108,13 @@ function handleOk() {
|
||||||
</template>
|
</template>
|
||||||
</Input>
|
</Input>
|
||||||
<Modal
|
<Modal
|
||||||
class="!w-[50vw]"
|
|
||||||
v-model:open="open"
|
v-model:open="open"
|
||||||
title="选择关联订单"
|
title="选择关联订单"
|
||||||
@ok="handleOk"
|
width="80%"
|
||||||
|
@cancel.stop="open = false"
|
||||||
|
@ok.stop="handleOk"
|
||||||
>
|
>
|
||||||
<Grid class="max-h-[600px]" table-title="销售订单列表(仅展示可出库)" />
|
<Grid table-title="销售订单列表(仅展示可出库)" />
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
<Modal
|
<Modal
|
||||||
:title="getTitle"
|
:title="getTitle"
|
||||||
class="w-3/4"
|
class="w-3/4"
|
||||||
|
:close-on-click-modal="false"
|
||||||
:show-confirm-button="formType !== 'detail'"
|
:show-confirm-button="formType !== 'detail'"
|
||||||
>
|
>
|
||||||
<Form class="mx-3">
|
<Form class="mx-3">
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const [Grid] = useVbenVxeGrid({
|
||||||
},
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useOrderGridColumns(),
|
columns: useOrderGridColumns(),
|
||||||
height: 'auto',
|
height: 520,
|
||||||
keepSource: true,
|
keepSource: true,
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
|
|
@ -108,12 +108,13 @@ function handleOk() {
|
||||||
</template>
|
</template>
|
||||||
</Input>
|
</Input>
|
||||||
<Modal
|
<Modal
|
||||||
class="!w-[50vw]"
|
|
||||||
v-model:open="open"
|
v-model:open="open"
|
||||||
title="选择关联订单"
|
title="选择关联订单"
|
||||||
@ok="handleOk"
|
width="80%"
|
||||||
|
@cancel.stop="open = false"
|
||||||
|
@ok.stop="handleOk"
|
||||||
>
|
>
|
||||||
<Grid class="max-h-[600px]" table-title="销售订单列表(仅展示可退货)" />
|
<Grid table-title="销售订单列表(仅展示可退货)" />
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,9 @@ function handleDetail(row: InfraApiErrorLogApi.ApiErrorLog) {
|
||||||
|
|
||||||
/** 处理已处理 / 已忽略的操作 */
|
/** 处理已处理 / 已忽略的操作 */
|
||||||
async function handleProcess(id: number, processStatus: number) {
|
async function handleProcess(id: number, processStatus: number) {
|
||||||
await confirm(`确认标记为${InfraApiErrorLogProcessStatusEnum.DONE ? '已处理' : '已忽略'}?`);
|
await confirm(
|
||||||
|
`确认标记为${InfraApiErrorLogProcessStatusEnum.DONE ? '已处理' : '已忽略'}?`,
|
||||||
|
);
|
||||||
const hideLoading = message.loading({
|
const hideLoading = message.loading({
|
||||||
content: '正在处理中...',
|
content: '正在处理中...',
|
||||||
duration: 0,
|
duration: 0,
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,9 @@ import { NotifyTemplateSelect } from '#/views/system/notify/template/components'
|
||||||
import { SmsTemplateSelect } from '#/views/system/sms/template/components';
|
import { SmsTemplateSelect } from '#/views/system/sms/template/components';
|
||||||
|
|
||||||
function hasReceiveType(values: Partial<Record<string, any>>, type: number) {
|
function hasReceiveType(values: Partial<Record<string, any>>, type: number) {
|
||||||
return Array.isArray(values.receiveTypes) && values.receiveTypes.includes(type);
|
return (
|
||||||
|
Array.isArray(values.receiveTypes) && values.receiveTypes.includes(type)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 新增/修改告警配置的表单 */
|
/** 新增/修改告警配置的表单 */
|
||||||
|
|
@ -155,7 +157,8 @@ export function useFormSchema(): VbenFormSchema[] {
|
||||||
component: markRaw(NotifyTemplateSelect),
|
component: markRaw(NotifyTemplateSelect),
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['receiveTypes'],
|
triggerFields: ['receiveTypes'],
|
||||||
show: (values) => hasReceiveType(values, IotAlertReceiveTypeEnum.NOTIFY),
|
show: (values) =>
|
||||||
|
hasReceiveType(values, IotAlertReceiveTypeEnum.NOTIFY),
|
||||||
trigger: async (values, formApi) => {
|
trigger: async (values, formApi) => {
|
||||||
if (
|
if (
|
||||||
!hasReceiveType(values, IotAlertReceiveTypeEnum.NOTIFY) &&
|
!hasReceiveType(values, IotAlertReceiveTypeEnum.NOTIFY) &&
|
||||||
|
|
|
||||||
|
|
@ -79,16 +79,13 @@ export function useAdvancedFormSchema(): VbenFormSchema[] {
|
||||||
},
|
},
|
||||||
rules: z
|
rules: z
|
||||||
.string()
|
.string()
|
||||||
.refine(
|
.refine((value) => {
|
||||||
(value) => {
|
const length = value.replaceAll(
|
||||||
const length = value.replaceAll(
|
/[\u4E00-\u9FA5\u3040-\u30FF]/g,
|
||||||
/[\u4E00-\u9FA5\u3040-\u30FF]/g,
|
'aa',
|
||||||
'aa',
|
).length;
|
||||||
).length;
|
return length >= 4 && length <= 64;
|
||||||
return length >= 4 && length <= 64;
|
}, '备注名称长度限制为 4~64 个字符,中文及日文算 2 个字符')
|
||||||
},
|
|
||||||
'备注名称长度限制为 4~64 个字符,中文及日文算 2 个字符',
|
|
||||||
)
|
|
||||||
.refine(
|
.refine(
|
||||||
(value) => /^[\u4E00-\u9FA5\u3040-\u30FF\w]+$/.test(value),
|
(value) => /^[\u4E00-\u9FA5\u3040-\u30FF\w]+$/.test(value),
|
||||||
'备注名称只能包含中文、英文字母、日文、数字和下划线(_)',
|
'备注名称只能包含中文、英文字母、日文、数字和下划线(_)',
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const mapDialogRef = ref<InstanceType<typeof MapDialog>>();
|
||||||
|
|
||||||
/** 是否有位置信息(合法经纬度 0 不应视为空) */
|
/** 是否有位置信息(合法经纬度 0 不应视为空) */
|
||||||
const hasLocation = computed(() => {
|
const hasLocation = computed(() => {
|
||||||
return props.device.longitude != null && props.device.latitude != null;
|
return props.device.longitude !== null && props.device.latitude !== null;
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 打开地图弹窗 */
|
/** 打开地图弹窗 */
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,9 @@ function handleEdit(row: IotDeviceGroupApi.DeviceGroup) {
|
||||||
/** 删除设备分组 */
|
/** 删除设备分组 */
|
||||||
async function handleDelete(row: IotDeviceGroupApi.DeviceGroup) {
|
async function handleDelete(row: IotDeviceGroupApi.DeviceGroup) {
|
||||||
if (row.deviceCount && row.deviceCount > 0) {
|
if (row.deviceCount && row.deviceCount > 0) {
|
||||||
message.warning(`分组「${row.name}」下存在 ${row.deviceCount} 台设备,无法删除`);
|
message.warning(
|
||||||
|
`分组「${row.name}」下存在 ${row.deviceCount} 台设备,无法删除`,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const hideLoading = message.loading({
|
const hideLoading = message.loading({
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,12 @@ const deviceList = ref<IotDeviceApi.Device[]>([]); // 设备分布列表
|
||||||
|
|
||||||
const hasData = computed(() => deviceList.value.length > 0); // 是否有数据
|
const hasData = computed(() => deviceList.value.length > 0); // 是否有数据
|
||||||
|
|
||||||
const stateOptions = computed(() =>
|
const stateOptions = computed(
|
||||||
getDictOptions(
|
() =>
|
||||||
DICT_TYPE.IOT_DEVICE_STATE,
|
getDictOptions(
|
||||||
'number',
|
DICT_TYPE.IOT_DEVICE_STATE,
|
||||||
) as NumberDictDataType[],
|
'number',
|
||||||
|
) as NumberDictDataType[],
|
||||||
); // 状态图例列表(从字典获取)
|
); // 状态图例列表(从字典获取)
|
||||||
|
|
||||||
const stateColorMap: Record<number, string> = {
|
const stateColorMap: Record<number, string> = {
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,7 @@ import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteOtaFirmware, getOtaFirmwarePage } from '#/api/iot/ota/firmware';
|
import { deleteOtaFirmware, getOtaFirmwarePage } from '#/api/iot/ota/firmware';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import {
|
import { getProductName, useGridColumns, useGridFormSchema } from './data';
|
||||||
getProductName,
|
|
||||||
useGridColumns,
|
|
||||||
useGridFormSchema,
|
|
||||||
} from './data';
|
|
||||||
import OtaFirmwareForm from './modules/form.vue';
|
import OtaFirmwareForm from './modules/form.vue';
|
||||||
|
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,9 @@ const queryParams = ref({
|
||||||
|
|
||||||
/** 获取分类名称 */
|
/** 获取分类名称 */
|
||||||
function getCategoryName(item: any) {
|
function getCategoryName(item: any) {
|
||||||
const category = props.categoryList.find((c: any) => c.id === item.categoryId);
|
const category = props.categoryList.find(
|
||||||
|
(c: any) => c.id === item.categoryId,
|
||||||
|
);
|
||||||
return item.categoryName || category?.name || '未分类';
|
return item.categoryName || category?.name || '未分类';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,11 +146,7 @@ onMounted(() => {
|
||||||
alt=""
|
alt=""
|
||||||
class="size-6 object-contain"
|
class="size-6 object-contain"
|
||||||
/>
|
/>
|
||||||
<IconifyIcon
|
<IconifyIcon v-else :icon="item.icon" class="text-xl" />
|
||||||
v-else
|
|
||||||
:icon="item.icon"
|
|
||||||
class="text-xl"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-3 min-w-0 flex-1">
|
<div class="ml-3 min-w-0 flex-1">
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -69,10 +69,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
||||||
slots: { default: 'actionsCol' },
|
slots: { default: 'actionsCol' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'lastTriggeredTime',
|
field: 'lastTriggerTime',
|
||||||
title: '最近触发',
|
title: '最近触发',
|
||||||
width: 180,
|
width: 180,
|
||||||
slots: { default: 'lastTriggeredTime' },
|
slots: { default: 'lastTriggerTime' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'createTime',
|
field: 'createTime',
|
||||||
|
|
|
||||||
|
|
@ -265,9 +265,7 @@ function handlePropertyChange(propertyInfo: any) {
|
||||||
triggerType === IotRuleSceneTriggerTypeEnum.DEVICE_EVENT_POST
|
triggerType === IotRuleSceneTriggerTypeEnum.DEVICE_EVENT_POST
|
||||||
"
|
"
|
||||||
:value="condition.value"
|
:value="condition.value"
|
||||||
@update:value="
|
@update:value="(value) => updateConditionField('value', value)"
|
||||||
(value) => updateConditionField('value', value)
|
|
||||||
"
|
|
||||||
placeholder="留空则事件发生即匹配"
|
placeholder="留空则事件发生即匹配"
|
||||||
/>
|
/>
|
||||||
<!-- 普通值输入 -->
|
<!-- 普通值输入 -->
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ const allOperators = [
|
||||||
label: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.name,
|
label: IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.name,
|
||||||
symbol: '≠',
|
symbol: '≠',
|
||||||
description: '值不相等时触发',
|
description: '值不相等时触发',
|
||||||
example: 'power != false',
|
example: 'power !== false',
|
||||||
supportedTypes: [
|
supportedTypes: [
|
||||||
IoTDataSpecsDataTypeEnum.INT,
|
IoTDataSpecsDataTypeEnum.INT,
|
||||||
IoTDataSpecsDataTypeEnum.FLOAT,
|
IoTDataSpecsDataTypeEnum.FLOAT,
|
||||||
|
|
|
||||||
|
|
@ -354,9 +354,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
<Tag color="success" class="m-0">{{ getActionSummary(row) }}</Tag>
|
<Tag color="success" class="m-0">{{ getActionSummary(row) }}</Tag>
|
||||||
</template>
|
</template>
|
||||||
<!-- 最近触发列 -->
|
<!-- 最近触发列 -->
|
||||||
<template #lastTriggeredTime="{ row }">
|
<template #lastTriggerTime="{ row }">
|
||||||
<span v-if="row.lastTriggeredTime">
|
<span v-if="row.lastTriggerTime">
|
||||||
{{ formatDateTime(row.lastTriggeredTime) }}
|
{{ formatDateTime(row.lastTriggerTime) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else class="text-muted-foreground">未触发</span>
|
<span v-else class="text-muted-foreground">未触发</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -216,10 +216,7 @@ function removeDataSpecs(val: any) {
|
||||||
label="标识符"
|
label="标识符"
|
||||||
name="identifier"
|
name="identifier"
|
||||||
>
|
>
|
||||||
<Input
|
<Input v-model:value="formData.identifier" placeholder="请输入标识符" />
|
||||||
v-model:value="formData.identifier"
|
|
||||||
placeholder="请输入标识符"
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<!-- 属性配置 -->
|
<!-- 属性配置 -->
|
||||||
<ThingModelProperty
|
<ThingModelProperty
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { onActivated, onMounted, reactive } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
import { CountTo } from '@vben/common-ui';
|
import { CountTo } from '@vben/common-ui';
|
||||||
|
import { fenToYuan } from '@vben/utils';
|
||||||
|
|
||||||
import { Card } from 'ant-design-vue';
|
import { Card } from 'ant-design-vue';
|
||||||
|
|
||||||
|
|
@ -78,7 +79,7 @@ async function loadProductData() {
|
||||||
/** 查询钱包充值数据 */
|
/** 查询钱包充值数据 */
|
||||||
async function loadWalletRechargeData() {
|
async function loadWalletRechargeData() {
|
||||||
const paySummary = await getWalletRechargePrice();
|
const paySummary = await getWalletRechargePrice();
|
||||||
data.rechargePrice.value = paySummary.rechargePrice;
|
data.rechargePrice.value = Number(fenToYuan(paySummary.rechargePrice || 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 跳转到对应页面 */
|
/** 跳转到对应页面 */
|
||||||
|
|
|
||||||
|
|
@ -130,11 +130,6 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
await modalApi.close();
|
await modalApi.close();
|
||||||
emit('success');
|
emit('success');
|
||||||
},
|
},
|
||||||
async onOpenChange(isOpen: boolean) {
|
|
||||||
if (!isOpen) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { MallBannerApi } from '#/api/mall/promotion/banner';
|
import type { MallBannerApi } from '#/api/mall/promotion/banner';
|
||||||
import type { SystemUserApi } from '#/api/system/user';
|
|
||||||
|
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
|
|
@ -19,7 +18,7 @@ import { $t } from '#/locales';
|
||||||
import { useFormSchema } from '../data';
|
import { useFormSchema } from '../data';
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
const emit = defineEmits(['success']);
|
||||||
const formData = ref<SystemUserApi.User>();
|
const formData = ref<MallBannerApi.Banner>();
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
return formData.value?.id
|
return formData.value?.id
|
||||||
? $t('ui.actionTitle.edit', ['Banner'])
|
? $t('ui.actionTitle.edit', ['Banner'])
|
||||||
|
|
|
||||||
|
|
@ -234,12 +234,10 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
>();
|
>();
|
||||||
if (props.multiple && Array.isArray(data) && data.length > 0) {
|
if (props.multiple && Array.isArray(data) && data.length > 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const tableData = gridApi.grid.getTableData().fullData;
|
const tableData = gridApi.grid.getTableData()
|
||||||
|
.fullData as MallCombinationActivityApi.CombinationActivity[];
|
||||||
data.forEach((activity) => {
|
data.forEach((activity) => {
|
||||||
const row = tableData.find(
|
const row = tableData.find((item) => item.id === activity.id);
|
||||||
(item: MallCombinationActivityApi.CombinationActivity) =>
|
|
||||||
item.id === activity.id,
|
|
||||||
);
|
|
||||||
if (row) {
|
if (row) {
|
||||||
gridApi.grid.setCheckboxRow(row, true);
|
gridApi.grid.setCheckboxRow(row, true);
|
||||||
}
|
}
|
||||||
|
|
@ -247,11 +245,9 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
}, 300);
|
}, 300);
|
||||||
} else if (!props.multiple && data && !Array.isArray(data)) {
|
} else if (!props.multiple && data && !Array.isArray(data)) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const tableData = gridApi.grid.getTableData().fullData;
|
const tableData = gridApi.grid.getTableData()
|
||||||
const row = tableData.find(
|
.fullData as MallCombinationActivityApi.CombinationActivity[];
|
||||||
(item: MallCombinationActivityApi.CombinationActivity) =>
|
const row = tableData.find((item) => item.id === data.id);
|
||||||
item.id === data.id,
|
|
||||||
);
|
|
||||||
if (row) {
|
if (row) {
|
||||||
gridApi.grid.setRadioRow(row);
|
gridApi.grid.setRadioRow(row);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { Ref } from 'vue';
|
||||||
|
|
||||||
import type { ComponentStyle } from '../util';
|
import type { ComponentStyle } from '../util';
|
||||||
|
|
||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
|
|
@ -28,6 +30,7 @@ defineOptions({ name: 'ComponentContainer' });
|
||||||
const props = defineProps<{ modelValue: ComponentStyle }>();
|
const props = defineProps<{ modelValue: ComponentStyle }>();
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
const formData = useVModel(props, 'modelValue', emit);
|
const formData = useVModel(props, 'modelValue', emit);
|
||||||
|
const formStyleValues = formData as unknown as Ref<Record<string, number>>;
|
||||||
|
|
||||||
const treeData: any[] = [
|
const treeData: any[] = [
|
||||||
{
|
{
|
||||||
|
|
@ -182,9 +185,7 @@ function handleSliderChange(prop: string) {
|
||||||
<Row>
|
<Row>
|
||||||
<Col :span="19">
|
<Col :span="19">
|
||||||
<Slider
|
<Slider
|
||||||
v-model:value="
|
v-model:value="formStyleValues[dataRef.prop]"
|
||||||
formData[dataRef.prop as keyof ComponentStyle]
|
|
||||||
"
|
|
||||||
:max="100"
|
:max="100"
|
||||||
:min="0"
|
:min="0"
|
||||||
@change="handleSliderChange(dataRef.prop)"
|
@change="handleSliderChange(dataRef.prop)"
|
||||||
|
|
@ -196,9 +197,7 @@ function handleSliderChange(prop: string) {
|
||||||
class="w-[50px]"
|
class="w-[50px]"
|
||||||
:max="100"
|
:max="100"
|
||||||
:min="0"
|
:min="0"
|
||||||
v-model:value="
|
v-model:value="formStyleValues[dataRef.prop]"
|
||||||
formData[dataRef.prop as keyof ComponentStyle]
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { StyleValue } from 'vue';
|
import type { CSSProperties } from 'vue';
|
||||||
|
|
||||||
import type { HotZoneItemProperty } from '../../config';
|
import type { HotZoneItemProperty } from '../../config';
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@ export enum CONTROL_TYPE_ENUM {
|
||||||
export interface ControlDot {
|
export interface ControlDot {
|
||||||
position: string;
|
position: string;
|
||||||
types: CONTROL_TYPE_ENUM[];
|
types: CONTROL_TYPE_ENUM[];
|
||||||
style: StyleValue;
|
style: CSSProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 热区的 8 个控制点 */
|
/** 热区的 8 个控制点 */
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Rect } from '../../../../magic-cube-editor/util';
|
||||||
import type { ComponentStyle, DiyComponent } from '../../../util';
|
import type { ComponentStyle, DiyComponent } from '../../../util';
|
||||||
|
|
||||||
/** 广告魔方属性 */
|
/** 广告魔方属性 */
|
||||||
|
|
@ -10,13 +11,9 @@ export interface MagicCubeProperty {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 广告魔方项目属性 */
|
/** 广告魔方项目属性 */
|
||||||
export interface MagicCubeItemProperty {
|
export interface MagicCubeItemProperty extends Rect {
|
||||||
imgUrl: string; // 图标链接
|
imgUrl: string; // 图标链接
|
||||||
url: string; // 链接
|
url: string; // 链接
|
||||||
width: number; // 宽
|
|
||||||
height: number; // 高
|
|
||||||
top: number; // 上
|
|
||||||
left: number; // 左
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 定义组件 */
|
/** 定义组件 */
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Rect } from '../../../../magic-cube-editor/util';
|
||||||
import type { DiyComponent } from '../../../util';
|
import type { DiyComponent } from '../../../util';
|
||||||
|
|
||||||
/** 顶部导航栏属性 */
|
/** 顶部导航栏属性 */
|
||||||
|
|
@ -16,12 +17,8 @@ export interface NavigationBarProperty {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 顶部导航栏 - 单元格 属性 */
|
/** 顶部导航栏 - 单元格 属性 */
|
||||||
export interface NavigationBarCellProperty {
|
export interface NavigationBarCellProperty extends Rect {
|
||||||
type: 'image' | 'search' | 'text'; // 类型:文字 | 图片 | 搜索框
|
type: 'image' | 'search' | 'text'; // 类型:文字 | 图片 | 搜索框
|
||||||
width: number; // 宽度
|
|
||||||
height: number; // 高度
|
|
||||||
top: number; // 顶部位置
|
|
||||||
left: number; // 左侧位置
|
|
||||||
text: string; // 文字内容
|
text: string; // 文字内容
|
||||||
textColor: string; // 文字颜色
|
textColor: string; // 文字颜色
|
||||||
imgUrl: string; // 图片地址
|
imgUrl: string; // 图片地址
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ const emit = defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
const formData = useVModel(props, 'modelValue', emit);
|
const formData = useVModel(props, 'modelValue', emit);
|
||||||
const rules = {
|
const rules = {
|
||||||
content: [{ required: true, message: '请输入公告', trigger: 'blur' }],
|
content: [
|
||||||
|
{ required: true, message: '请输入公告', trigger: 'blur' as const },
|
||||||
|
],
|
||||||
}; // 表单校验
|
}; // 表单校验
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ const emits = defineEmits(['reset', 'save', 'update:modelValue']); // 工具栏
|
||||||
// margin: 4,
|
// margin: 4,
|
||||||
// }); // 预览二维码
|
// }); // 预览二维码
|
||||||
|
|
||||||
const componentLibrary = ref(); // 左侧组件库
|
|
||||||
const pageConfigComponent = ref<DiyComponent<any>>(
|
const pageConfigComponent = ref<DiyComponent<any>>(
|
||||||
cloneDeep(PAGE_CONFIG_COMPONENT),
|
cloneDeep(PAGE_CONFIG_COMPONENT),
|
||||||
); // 页面设置组件
|
); // 页面设置组件
|
||||||
|
|
@ -334,11 +333,7 @@ onMounted(() => {
|
||||||
<Row class="mt-4 h-[calc(80vh)]">
|
<Row class="mt-4 h-[calc(80vh)]">
|
||||||
<!-- 左侧:组件库(ComponentLibrary) -->
|
<!-- 左侧:组件库(ComponentLibrary) -->
|
||||||
<Col :span="6">
|
<Col :span="6">
|
||||||
<ComponentLibrary
|
<ComponentLibrary v-if="libs && libs.length > 0" :list="libs" />
|
||||||
v-if="libs && libs.length > 0"
|
|
||||||
ref="componentLibrary"
|
|
||||||
:list="libs"
|
|
||||||
/>
|
|
||||||
</Col>
|
</Col>
|
||||||
<!-- 中心:设计区域(ComponentContainer) -->
|
<!-- 中心:设计区域(ComponentContainer) -->
|
||||||
<Col :span="12">
|
<Col :span="12">
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,9 @@ async function handleStatusChange(
|
||||||
row: MallCouponTemplateApi.CouponTemplate,
|
row: MallCouponTemplateApi.CouponTemplate,
|
||||||
): Promise<boolean | undefined> {
|
): Promise<boolean | undefined> {
|
||||||
try {
|
try {
|
||||||
await confirm(`你要将${row.name}的状态切换为【${newStatus === CommonStatusEnum.ENABLE ? '启用' : '停用'}】吗?`);
|
await confirm(
|
||||||
|
`你要将${row.name}的状态切换为【${newStatus === CommonStatusEnum.ENABLE ? '启用' : '停用'}】吗?`,
|
||||||
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ import type { Emoji } from './tools/emoji';
|
||||||
import type { MallKefuConversationApi } from '#/api/mall/promotion/kefu/conversation';
|
import type { MallKefuConversationApi } from '#/api/mall/promotion/kefu/conversation';
|
||||||
import type { MallKefuMessageApi } from '#/api/mall/promotion/kefu/message';
|
import type { MallKefuMessageApi } from '#/api/mall/promotion/kefu/message';
|
||||||
|
|
||||||
import { computed, KeFuMessageContentTypeEnum, reactive, ref, toRefs, unref, watch } from 'vue';
|
import { computed, reactive, ref, toRefs, unref, watch } from 'vue';
|
||||||
|
|
||||||
import { UserTypeEnum } from '@vben/constants';
|
import { KeFuMessageContentTypeEnum, UserTypeEnum } from '@vben/constants';
|
||||||
import { IconifyIcon } from '@vben/icons';
|
import { IconifyIcon } from '@vben/icons';
|
||||||
import { formatDate, isEmpty, jsonParse } from '@vben/utils';
|
import { formatDate, isEmpty, jsonParse } from '@vben/utils';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,12 +196,10 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
>();
|
>();
|
||||||
if (props.multiple && Array.isArray(data) && data.length > 0) {
|
if (props.multiple && Array.isArray(data) && data.length > 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const tableData = gridApi.grid.getTableData().fullData;
|
const tableData = gridApi.grid.getTableData()
|
||||||
|
.fullData as MallPointActivityApi.PointActivity[];
|
||||||
data.forEach((activity) => {
|
data.forEach((activity) => {
|
||||||
const row = tableData.find(
|
const row = tableData.find((item) => item.id === activity.id);
|
||||||
(item: MallPointActivityApi.PointActivity) =>
|
|
||||||
item.id === activity.id,
|
|
||||||
);
|
|
||||||
if (row) {
|
if (row) {
|
||||||
gridApi.grid.setCheckboxRow(row, true);
|
gridApi.grid.setCheckboxRow(row, true);
|
||||||
}
|
}
|
||||||
|
|
@ -209,10 +207,9 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
}, 300);
|
}, 300);
|
||||||
} else if (!props.multiple && data && !Array.isArray(data)) {
|
} else if (!props.multiple && data && !Array.isArray(data)) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const tableData = gridApi.grid.getTableData().fullData;
|
const tableData = gridApi.grid.getTableData()
|
||||||
const row = tableData.find(
|
.fullData as MallPointActivityApi.PointActivity[];
|
||||||
(item: MallPointActivityApi.PointActivity) => item.id === data.id,
|
const row = tableData.find((item) => item.id === data.id);
|
||||||
);
|
|
||||||
if (row) {
|
if (row) {
|
||||||
gridApi.grid.setRadioRow(row);
|
gridApi.grid.setRadioRow(row);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,10 @@ const hasFestivalDay = computed(() => {
|
||||||
<div class="flex h-full flex-col overflow-hidden p-1">
|
<div class="flex h-full flex-col overflow-hidden p-1">
|
||||||
<!-- 顶部:日期数字 + 上班/休息标签 -->
|
<!-- 顶部:日期数字 + 上班/休息标签 -->
|
||||||
<div class="flex shrink-0 items-center justify-between">
|
<div class="flex shrink-0 items-center justify-between">
|
||||||
<span class="text-base font-medium" :class="{ 'text-red-500': isWeekend }">
|
<span
|
||||||
|
class="text-base font-medium"
|
||||||
|
:class="{ 'text-red-500': isWeekend }"
|
||||||
|
>
|
||||||
{{ dayNumber }}
|
{{ dayNumber }}
|
||||||
</span>
|
</span>
|
||||||
<Tag v-if="isHoliday" color="green" class="!m-0"> 休 </Tag>
|
<Tag v-if="isHoliday" color="green" class="!m-0"> 休 </Tag>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,9 @@ const legendItems: Array<{ color: string; label: string }> = [
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</span>
|
</span>
|
||||||
<span class="flex items-center gap-1">
|
<span class="flex items-center gap-1">
|
||||||
<span class="inline-block h-2.5 w-2.5 shrink-0 rounded-sm bg-[#f56c6c] opacity-60"></span>
|
<span
|
||||||
|
class="inline-block h-2.5 w-2.5 shrink-0 rounded-sm bg-[#f56c6c] opacity-60"
|
||||||
|
></span>
|
||||||
<span class="text-red-500">红色日期</span>
|
<span class="text-red-500">红色日期</span>
|
||||||
= 周末
|
= 周末
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,9 @@ onMounted(async () => {
|
||||||
<template>
|
<template>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<!-- 左侧:班组列表选择 -->
|
<!-- 左侧:班组列表选择 -->
|
||||||
<div class="border-border mr-3 w-[150px] shrink-0 overflow-hidden rounded border">
|
<div
|
||||||
|
class="border-border mr-3 w-[150px] shrink-0 overflow-hidden rounded border"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
v-for="team in teamList"
|
v-for="team in teamList"
|
||||||
:key="team.id"
|
:key="team.id"
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,9 @@ onMounted(() => {
|
||||||
<template>
|
<template>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<!-- 左侧:班组类型选择 -->
|
<!-- 左侧:班组类型选择 -->
|
||||||
<div class="border-border mr-3 w-[150px] shrink-0 overflow-hidden rounded border">
|
<div
|
||||||
|
class="border-border mr-3 w-[150px] shrink-0 overflow-hidden rounded border"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
v-for="item in typeOptions"
|
v-for="item in typeOptions"
|
||||||
:key="item.value as number"
|
:key="item.value as number"
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,12 @@ function getLunarInfo(day: string) {
|
||||||
termName,
|
termName,
|
||||||
};
|
};
|
||||||
} catch {
|
} catch {
|
||||||
return { lunarFestival: '', lunarText: '', solarFestival: '', termName: '' };
|
return {
|
||||||
|
lunarFestival: '',
|
||||||
|
lunarText: '',
|
||||||
|
solarFestival: '',
|
||||||
|
termName: '',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,15 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
}
|
}
|
||||||
modalApi.lock();
|
modalApi.lock();
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const data = (await formApi.getValues()) as MesCalHolidayApi.Holiday & { dayDisplay?: string };
|
const data = (await formApi.getValues()) as MesCalHolidayApi.Holiday & {
|
||||||
|
dayDisplay?: string;
|
||||||
|
};
|
||||||
try {
|
try {
|
||||||
await saveHoliday({ day: data.day, type: data.type, remark: data.remark });
|
await saveHoliday({
|
||||||
|
day: data.day,
|
||||||
|
type: data.type,
|
||||||
|
remark: data.remark,
|
||||||
|
});
|
||||||
// 关闭并提示
|
// 关闭并提示
|
||||||
await modalApi.close();
|
await modalApi.close();
|
||||||
emit('success');
|
emit('success');
|
||||||
|
|
@ -54,7 +60,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
if (!data?.day) {
|
if (!data?.day) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const timestamp = dayjs(data.day + ' 00:00:00').valueOf();
|
const timestamp = dayjs(`${data.day} 00:00:00`).valueOf();
|
||||||
await formApi.setValues({
|
await formApi.setValues({
|
||||||
day: timestamp,
|
day: timestamp,
|
||||||
dayDisplay: data.day,
|
dayDisplay: data.day,
|
||||||
|
|
@ -63,7 +69,9 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
});
|
});
|
||||||
modalApi.lock();
|
modalApi.lock();
|
||||||
try {
|
try {
|
||||||
const holiday = await getHolidayByDay(dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss'));
|
const holiday = await getHolidayByDay(
|
||||||
|
dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
|
);
|
||||||
if (holiday) {
|
if (holiday) {
|
||||||
await formApi.setValues({
|
await formApi.setValues({
|
||||||
type: holiday.type ?? HolidayType.WORKDAY,
|
type: holiday.type ?? HolidayType.WORKDAY,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,13 @@ import type { MesCalPlanApi } from '#/api/mes/cal/plan';
|
||||||
|
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
import { DICT_TYPE, MesAutoCodeRuleCode, MesCalPlanStatusEnum, MesCalShiftMethodEnum, MesCalShiftTypeEnum } from '@vben/constants';
|
import {
|
||||||
|
DICT_TYPE,
|
||||||
|
MesAutoCodeRuleCode,
|
||||||
|
MesCalPlanStatusEnum,
|
||||||
|
MesCalShiftMethodEnum,
|
||||||
|
MesCalShiftTypeEnum,
|
||||||
|
} from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
|
|
||||||
import { Button } from 'ant-design-vue';
|
import { Button } from 'ant-design-vue';
|
||||||
|
|
@ -55,7 +61,9 @@ export function useFormSchema(
|
||||||
{
|
{
|
||||||
type: 'default',
|
type: 'default',
|
||||||
onClick: async () => {
|
onClick: async () => {
|
||||||
const code = await generateAutoCode(MesAutoCodeRuleCode.CAL_PLAN_CODE);
|
const code = await generateAutoCode(
|
||||||
|
MesAutoCodeRuleCode.CAL_PLAN_CODE,
|
||||||
|
);
|
||||||
await formApi?.setFieldValue('code', code);
|
await formApi?.setFieldValue('code', code);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -126,7 +134,8 @@ export function useFormSchema(
|
||||||
},
|
},
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['shiftType'],
|
triggerFields: ['shiftType'],
|
||||||
show: (values) => !!values.shiftType && values.shiftType !== MesCalShiftTypeEnum.SINGLE,
|
show: (values) =>
|
||||||
|
!!values.shiftType && values.shiftType !== MesCalShiftTypeEnum.SINGLE,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -237,8 +246,18 @@ export function useGridColumns(): VxeTableGridOptions<MesCalPlanApi.Plan>['colum
|
||||||
props: { type: DICT_TYPE.MES_CAL_CALENDAR_TYPE },
|
props: { type: DICT_TYPE.MES_CAL_CALENDAR_TYPE },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ field: 'startDate', title: '开始日期', width: 150, formatter: 'formatDate' },
|
{
|
||||||
{ field: 'endDate', title: '结束日期', width: 150, formatter: 'formatDate' },
|
field: 'startDate',
|
||||||
|
title: '开始日期',
|
||||||
|
width: 150,
|
||||||
|
formatter: 'formatDate',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'endDate',
|
||||||
|
title: '结束日期',
|
||||||
|
width: 150,
|
||||||
|
formatter: 'formatDate',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'shiftType',
|
field: 'shiftType',
|
||||||
title: '轮班方式',
|
title: '轮班方式',
|
||||||
|
|
@ -266,7 +285,12 @@ export function useGridColumns(): VxeTableGridOptions<MesCalPlanApi.Plan>['colum
|
||||||
props: { type: DICT_TYPE.MES_CAL_PLAN_STATUS },
|
props: { type: DICT_TYPE.MES_CAL_PLAN_STATUS },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ field: 'createTime', title: '创建时间', width: 180, formatter: 'formatDateTime' },
|
{
|
||||||
|
field: 'createTime',
|
||||||
|
title: '创建时间',
|
||||||
|
width: 180,
|
||||||
|
formatter: 'formatDateTime',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: 160,
|
width: 160,
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,11 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
query: async ({ page }, formValues) =>
|
query: async ({ page }, formValues) =>
|
||||||
await getPlanPage({ pageNo: page.currentPage, pageSize: page.pageSize, ...formValues }),
|
await getPlanPage({
|
||||||
|
pageNo: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
...formValues,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
rowConfig: {
|
rowConfig: {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,12 @@ import { MesCalPlanStatusEnum } from '@vben/constants';
|
||||||
import { Button, message, Popconfirm, Tabs } from 'ant-design-vue';
|
import { Button, message, Popconfirm, Tabs } from 'ant-design-vue';
|
||||||
|
|
||||||
import { useVbenForm } from '#/adapter/form';
|
import { useVbenForm } from '#/adapter/form';
|
||||||
import { confirmPlan, createPlan, getPlan, updatePlan } from '#/api/mes/cal/plan';
|
import {
|
||||||
|
confirmPlan,
|
||||||
|
createPlan,
|
||||||
|
getPlan,
|
||||||
|
updatePlan,
|
||||||
|
} from '#/api/mes/cal/plan';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useFormSchema } from '../data';
|
import { useFormSchema } from '../data';
|
||||||
|
|
@ -24,7 +29,9 @@ const subTabsName = ref('shift'); // 当前资源页签
|
||||||
const formData = ref<MesCalPlanApi.Plan>();
|
const formData = ref<MesCalPlanApi.Plan>();
|
||||||
const isDetail = computed(() => formType.value === 'detail'); // 是否查看模式
|
const isDetail = computed(() => formType.value === 'detail'); // 是否查看模式
|
||||||
const canConfirm = computed(
|
const canConfirm = computed(
|
||||||
() => formType.value === 'update' && formData.value?.status === MesCalPlanStatusEnum.PREPARE,
|
() =>
|
||||||
|
formType.value === 'update' &&
|
||||||
|
formData.value?.status === MesCalPlanStatusEnum.PREPARE,
|
||||||
); // 是否可确认计划
|
); // 是否可确认计划
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
if (formType.value === 'detail') {
|
if (formType.value === 'detail') {
|
||||||
|
|
@ -85,7 +92,11 @@ const [Modal, modalApi] = useVbenModal({
|
||||||
try {
|
try {
|
||||||
if (formType.value === 'create') {
|
if (formType.value === 'create') {
|
||||||
const id = await createPlan(data);
|
const id = await createPlan(data);
|
||||||
formData.value = { ...data, id: id as number, status: MesCalPlanStatusEnum.PREPARE };
|
formData.value = {
|
||||||
|
...data,
|
||||||
|
id: id as number,
|
||||||
|
status: MesCalPlanStatusEnum.PREPARE,
|
||||||
|
};
|
||||||
await formApi.setFieldValue('id', id);
|
await formApi.setFieldValue('id', id);
|
||||||
formType.value = 'update';
|
formType.value = 'update';
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,19 @@ import {
|
||||||
} from '#/api/mes/cal/plan/shift';
|
} from '#/api/mes/cal/plan/shift';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{ formType?: FormType; planId: number }>(), {
|
const props = withDefaults(
|
||||||
formType: 'update',
|
defineProps<{ formType?: FormType; planId: number }>(),
|
||||||
});
|
{
|
||||||
|
formType: 'update',
|
||||||
|
},
|
||||||
|
);
|
||||||
const isEditable = computed(() => props.formType !== 'detail'); // 是否可编辑
|
const isEditable = computed(() => props.formType !== 'detail'); // 是否可编辑
|
||||||
const formOpen = ref(false); // 班次表单是否打开
|
const formOpen = ref(false); // 班次表单是否打开
|
||||||
const formLoading = ref(false); // 班次表单提交中
|
const formLoading = ref(false); // 班次表单提交中
|
||||||
const shiftFormType = ref<'create' | 'update'>('create'); // 班次表单模式
|
const shiftFormType = ref<'create' | 'update'>('create'); // 班次表单模式
|
||||||
const formTitle = computed(() => (shiftFormType.value === 'create' ? '添加班次' : '修改班次'));
|
const formTitle = computed(() =>
|
||||||
|
shiftFormType.value === 'create' ? '添加班次' : '修改班次',
|
||||||
|
);
|
||||||
const list = ref<MesCalPlanShiftApi.PlanShift[]>([]); // 班次列表
|
const list = ref<MesCalPlanShiftApi.PlanShift[]>([]); // 班次列表
|
||||||
|
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
|
|
@ -157,7 +162,10 @@ async function getList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 打开班次表单 */
|
/** 打开班次表单 */
|
||||||
async function openForm(type: 'create' | 'update', row?: MesCalPlanShiftApi.PlanShift) {
|
async function openForm(
|
||||||
|
type: 'create' | 'update',
|
||||||
|
row?: MesCalPlanShiftApi.PlanShift,
|
||||||
|
) {
|
||||||
formOpen.value = true;
|
formOpen.value = true;
|
||||||
shiftFormType.value = type;
|
shiftFormType.value = type;
|
||||||
await formApi.resetForm();
|
await formApi.resetForm();
|
||||||
|
|
@ -173,7 +181,9 @@ async function submitForm() {
|
||||||
formLoading.value = true;
|
formLoading.value = true;
|
||||||
try {
|
try {
|
||||||
const data = (await formApi.getValues()) as MesCalPlanShiftApi.PlanShift;
|
const data = (await formApi.getValues()) as MesCalPlanShiftApi.PlanShift;
|
||||||
await (shiftFormType.value === 'create' ? createPlanShift(data) : updatePlanShift(data));
|
await (shiftFormType.value === 'create'
|
||||||
|
? createPlanShift(data)
|
||||||
|
: updatePlanShift(data));
|
||||||
formOpen.value = false;
|
formOpen.value = false;
|
||||||
message.success($t('ui.actionMessage.operationSuccess'));
|
message.success($t('ui.actionMessage.operationSuccess'));
|
||||||
await getList();
|
await getList();
|
||||||
|
|
@ -204,14 +214,24 @@ watch(
|
||||||
<div>
|
<div>
|
||||||
<div v-if="isEditable" class="mb-3 flex items-center justify-start">
|
<div v-if="isEditable" class="mb-3 flex items-center justify-start">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[{ label: '添加班次', type: 'primary', onClick: openForm.bind(null, 'create') }]"
|
:actions="[
|
||||||
|
{
|
||||||
|
label: '添加班次',
|
||||||
|
type: 'primary',
|
||||||
|
onClick: openForm.bind(null, 'create'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Grid class="w-full">
|
<Grid class="w-full">
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
{ label: '编辑', type: 'link', onClick: openForm.bind(null, 'update', row) },
|
{
|
||||||
|
label: '编辑',
|
||||||
|
type: 'link',
|
||||||
|
onClick: openForm.bind(null, 'update', row),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '删除',
|
label: '删除',
|
||||||
type: 'link',
|
type: 'link',
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,21 @@ import { computed, ref, watch } from 'vue';
|
||||||
import { Card, message } from 'ant-design-vue';
|
import { Card, message } from 'ant-design-vue';
|
||||||
|
|
||||||
import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { createPlanTeam, deletePlanTeam, getPlanTeamListByPlan } from '#/api/mes/cal/plan/team';
|
import {
|
||||||
|
createPlanTeam,
|
||||||
|
deletePlanTeam,
|
||||||
|
getPlanTeamListByPlan,
|
||||||
|
} from '#/api/mes/cal/plan/team';
|
||||||
import { getTeamMemberListByTeam } from '#/api/mes/cal/team/member';
|
import { getTeamMemberListByTeam } from '#/api/mes/cal/team/member';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
import { CalTeamSelectDialog } from '#/views/mes/cal/team/components';
|
import { CalTeamSelectDialog } from '#/views/mes/cal/team/components';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{ formType?: FormType; planId: number }>(), {
|
const props = withDefaults(
|
||||||
formType: 'update',
|
defineProps<{ formType?: FormType; planId: number }>(),
|
||||||
});
|
{
|
||||||
|
formType: 'update',
|
||||||
|
},
|
||||||
|
);
|
||||||
const isEditable = computed(() => props.formType !== 'detail'); // 是否可编辑
|
const isEditable = computed(() => props.formType !== 'detail'); // 是否可编辑
|
||||||
const list = ref<MesCalPlanTeamApi.PlanTeam[]>([]); // 计划班组列表
|
const list = ref<MesCalPlanTeamApi.PlanTeam[]>([]); // 计划班组列表
|
||||||
const memberList = ref<MesCalTeamMemberApi.TeamMember[]>([]); // 班组成员列表
|
const memberList = ref<MesCalTeamMemberApi.TeamMember[]>([]); // 班组成员列表
|
||||||
|
|
@ -61,7 +68,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
},
|
},
|
||||||
} as VxeTableGridOptions<MesCalPlanTeamApi.PlanTeam>,
|
} as VxeTableGridOptions<MesCalPlanTeamApi.PlanTeam>,
|
||||||
gridEvents: {
|
gridEvents: {
|
||||||
cellClick: ({ row }: { row: MesCalPlanTeamApi.PlanTeam }) => handleTeamSelect(row),
|
cellClick: ({ row }: { row: MesCalPlanTeamApi.PlanTeam }) =>
|
||||||
|
handleTeamSelect(row),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -123,13 +131,17 @@ async function handleTeamSelect(row?: MesCalPlanTeamApi.PlanTeam) {
|
||||||
|
|
||||||
/** 打开班组选择弹窗 */
|
/** 打开班组选择弹窗 */
|
||||||
function openTeamSelect() {
|
function openTeamSelect() {
|
||||||
teamDialogRef.value?.open(list.value.map((item) => item.teamId!).filter(Boolean));
|
teamDialogRef.value?.open(
|
||||||
|
list.value.map((item) => item.teamId!).filter(Boolean),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 处理班组选择 */
|
/** 处理班组选择 */
|
||||||
async function handleTeamsSelected(rows: MesCalTeamApi.Team[]) {
|
async function handleTeamsSelected(rows: MesCalTeamApi.Team[]) {
|
||||||
const existingTeamIds = new Set(list.value.map((item) => item.teamId));
|
const existingTeamIds = new Set(list.value.map((item) => item.teamId));
|
||||||
const newTeams = rows.filter((team) => team.id && !existingTeamIds.has(team.id));
|
const newTeams = rows.filter(
|
||||||
|
(team) => team.id && !existingTeamIds.has(team.id),
|
||||||
|
);
|
||||||
if (newTeams.length === 0) {
|
if (newTeams.length === 0) {
|
||||||
message.warning('所选班组已全部添加过');
|
message.warning('所选班组已全部添加过');
|
||||||
return;
|
return;
|
||||||
|
|
@ -139,7 +151,7 @@ async function handleTeamsSelected(rows: MesCalTeamApi.Team[]) {
|
||||||
for (const team of newTeams) {
|
for (const team of newTeams) {
|
||||||
await createPlanTeam({ planId: props.planId, teamId: team.id });
|
await createPlanTeam({ planId: props.planId, teamId: team.id });
|
||||||
}
|
}
|
||||||
message.success('成功添加 ' + newTeams.length + ' 个班组');
|
message.success(`成功添加 ${newTeams.length} 个班组`);
|
||||||
await getList();
|
await getList();
|
||||||
} finally {
|
} finally {
|
||||||
gridApi.setLoading(false);
|
gridApi.setLoading(false);
|
||||||
|
|
@ -170,7 +182,11 @@ watch(
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="isEditable" class="mb-3 flex items-center justify-start">
|
<div v-if="isEditable" class="mb-3 flex items-center justify-start">
|
||||||
<TableAction :actions="[{ label: '添加班组', type: 'primary', onClick: openTeamSelect }]" />
|
<TableAction
|
||||||
|
:actions="[
|
||||||
|
{ label: '添加班组', type: 'primary', onClick: openTeamSelect },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-5 gap-4">
|
<div class="grid grid-cols-5 gap-4">
|
||||||
<div class="col-span-3">
|
<div class="col-span-3">
|
||||||
|
|
@ -195,15 +211,23 @@ watch(
|
||||||
<div class="col-span-2">
|
<div class="col-span-2">
|
||||||
<Card class="h-full" size="small">
|
<Card class="h-full" size="small">
|
||||||
<template #title>
|
<template #title>
|
||||||
{{ selectedTeamName ? `「${selectedTeamName}」班组成员` : '班组成员' }}
|
{{
|
||||||
|
selectedTeamName ? `「${selectedTeamName}」班组成员` : '班组成员'
|
||||||
|
}}
|
||||||
</template>
|
</template>
|
||||||
<div v-if="!selectedTeamId">
|
<div v-if="!selectedTeamId">
|
||||||
<div class="py-8 text-center text-gray-400">请点击左侧班组查看成员</div>
|
<div class="py-8 text-center text-gray-400">
|
||||||
|
请点击左侧班组查看成员
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<MemberGrid v-else class="w-full" />
|
<MemberGrid v-else class="w-full" />
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CalTeamSelectDialog ref="teamDialogRef" :multiple="true" @selected="handleTeamsSelected" />
|
<CalTeamSelectDialog
|
||||||
|
ref="teamDialogRef"
|
||||||
|
:multiple="true"
|
||||||
|
@selected="handleTeamsSelected"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@ function handleCellDblclick({ row }: { row: MesCalTeamApi.Team }) {
|
||||||
const records = gridApi.grid.getCheckboxRecords() as MesCalTeamApi.Team[];
|
const records = gridApi.grid.getCheckboxRecords() as MesCalTeamApi.Team[];
|
||||||
const checked = records.some((item) => item.id === row.id);
|
const checked = records.some((item) => item.id === row.id);
|
||||||
gridApi.grid.setCheckboxRow(row, !checked);
|
gridApi.grid.setCheckboxRow(row, !checked);
|
||||||
selectedRows.value = gridApi.grid.getCheckboxRecords() as MesCalTeamApi.Team[];
|
selectedRows.value =
|
||||||
|
gridApi.grid.getCheckboxRecords() as MesCalTeamApi.Team[];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
selectedRows.value = [row];
|
selectedRows.value = [row];
|
||||||
|
|
@ -51,7 +52,8 @@ function applyPreSelection() {
|
||||||
gridApi.grid.setCheckboxRow(row, true);
|
gridApi.grid.setCheckboxRow(row, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selectedRows.value = gridApi.grid.getCheckboxRecords() as MesCalTeamApi.Team[];
|
selectedRows.value =
|
||||||
|
gridApi.grid.getCheckboxRecords() as MesCalTeamApi.Team[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const [Grid, gridApi] = useVbenVxeGrid({
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
|
|
@ -70,7 +72,11 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
query: async ({ page }, formValues) =>
|
query: async ({ page }, formValues) =>
|
||||||
await getTeamPage({ pageNo: page.currentPage, pageSize: page.pageSize, ...formValues }),
|
await getTeamPage({
|
||||||
|
pageNo: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
...formValues,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
rowConfig: {
|
rowConfig: {
|
||||||
|
|
@ -97,7 +103,10 @@ async function resetQueryState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 打开班组选择弹窗 */
|
/** 打开班组选择弹窗 */
|
||||||
async function openModal(selectedIds?: number[], options?: { multiple?: boolean }) {
|
async function openModal(
|
||||||
|
selectedIds?: number[],
|
||||||
|
options?: { multiple?: boolean },
|
||||||
|
) {
|
||||||
open.value = true;
|
open.value = true;
|
||||||
multiple.value = options?.multiple ?? true;
|
multiple.value = options?.multiple ?? true;
|
||||||
preSelectedIds.value = selectedIds || [];
|
preSelectedIds.value = selectedIds || [];
|
||||||
|
|
@ -120,7 +129,10 @@ function handleConfirm() {
|
||||||
message.warning(multiple.value ? '请至少选择一条数据' : '请选择一条数据');
|
message.warning(multiple.value ? '请至少选择一条数据' : '请选择一条数据');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit('selected', multiple.value ? selectedRows.value : [selectedRows.value[0]!]);
|
emit(
|
||||||
|
'selected',
|
||||||
|
multiple.value ? selectedRows.value : [selectedRows.value[0]!],
|
||||||
|
);
|
||||||
open.value = false;
|
open.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,9 @@ function openDialog() {
|
||||||
if (props.disabled) {
|
if (props.disabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dialogRef.value?.open(props.modelValue ? [props.modelValue] : [], { multiple: false });
|
dialogRef.value?.open(props.modelValue ? [props.modelValue] : [], {
|
||||||
|
multiple: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 处理弹窗选择 */
|
/** 处理弹窗选择 */
|
||||||
|
|
@ -79,6 +81,10 @@ onMounted(loadTeamList);
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
/>
|
/>
|
||||||
<Button :disabled="disabled" @click="openDialog">选择</Button>
|
<Button :disabled="disabled" @click="openDialog">选择</Button>
|
||||||
<CalTeamSelectDialog ref="dialogRef" :multiple="false" @selected="handleSelected" />
|
<CalTeamSelectDialog
|
||||||
|
ref="dialogRef"
|
||||||
|
:multiple="false"
|
||||||
|
@selected="handleSelected"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,9 @@ export function useFormSchema(
|
||||||
{
|
{
|
||||||
type: 'default',
|
type: 'default',
|
||||||
onClick: async () => {
|
onClick: async () => {
|
||||||
const code = await generateAutoCode(MesAutoCodeRuleCode.CAL_TEAM_CODE);
|
const code = await generateAutoCode(
|
||||||
|
MesAutoCodeRuleCode.CAL_TEAM_CODE,
|
||||||
|
);
|
||||||
await formApi?.setFieldValue('code', code);
|
await formApi?.setFieldValue('code', code);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -145,7 +147,12 @@ export function useGridColumns(): VxeTableGridOptions<MesCalTeamApi.Team>['colum
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ field: 'remark', title: '备注', minWidth: 180 },
|
{ field: 'remark', title: '备注', minWidth: 180 },
|
||||||
{ field: 'createTime', title: '创建时间', width: 180, formatter: 'formatDateTime' },
|
{
|
||||||
|
field: 'createTime',
|
||||||
|
title: '创建时间',
|
||||||
|
width: 180,
|
||||||
|
formatter: 'formatDateTime',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: 180,
|
width: 180,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import { $t } from '#/locales';
|
||||||
import { useFormSchema } from '../data';
|
import { useFormSchema } from '../data';
|
||||||
import MemberList from './member-list.vue';
|
import MemberList from './member-list.vue';
|
||||||
|
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
const emit = defineEmits(['success']);
|
||||||
const formType = ref<FormType>('create'); // 表单模式
|
const formType = ref<FormType>('create'); // 表单模式
|
||||||
const subTabsName = ref('member'); // 当前资源页签
|
const subTabsName = ref('member'); // 当前资源页签
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,15 @@ import {
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
import { getSimpleUserList } from '#/api/system/user';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{ formType?: FormType; teamId: number }>(), {
|
const props = withDefaults(
|
||||||
formType: 'update',
|
defineProps<{ formType?: FormType; teamId: number }>(),
|
||||||
});
|
{
|
||||||
const isEditable = computed(() => ['create', 'update'].includes(props.formType)); // 是否可编辑
|
formType: 'update',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const isEditable = computed(() =>
|
||||||
|
['create', 'update'].includes(props.formType),
|
||||||
|
); // 是否可编辑
|
||||||
const formOpen = ref(false); // 成员表单是否打开
|
const formOpen = ref(false); // 成员表单是否打开
|
||||||
const formLoading = ref(false); // 成员表单提交中
|
const formLoading = ref(false); // 成员表单提交中
|
||||||
const list = ref<MesCalTeamMemberApi.TeamMember[]>([]); // 成员列表
|
const list = ref<MesCalTeamMemberApi.TeamMember[]>([]); // 成员列表
|
||||||
|
|
@ -163,7 +168,9 @@ watch(
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="isEditable" class="mb-3 flex items-center justify-start">
|
<div v-if="isEditable" class="mb-3 flex items-center justify-start">
|
||||||
<TableAction :actions="[{ label: '添加成员', type: 'primary', onClick: openForm }]" />
|
<TableAction
|
||||||
|
:actions="[{ label: '添加成员', type: 'primary', onClick: openForm }]"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Grid class="w-full">
|
<Grid class="w-full">
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue