fix: lint

pull/358/MERGE
xingyu4j 2026-06-07 12:52:18 +08:00
parent aad62cf5ca
commit c376a60e83
712 changed files with 4236 additions and 2122 deletions

View File

@ -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,
});
} }

View File

@ -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,
});
} }
/** 查询物料产品详情 */ /** 查询物料产品详情 */

View File

@ -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}`,
);
} }
/** 新增工艺路线 */ /** 新增工艺路线 */

View File

@ -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}`,
);
} }
/** 新增缺陷类型 */ /** 新增缺陷类型 */

View File

@ -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',

View File

@ -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 }, });
);
} }
/** 查询过程检验单详情 */ /** 查询过程检验单详情 */

View File

@ -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 });

View File

@ -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 },

View File

@ -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);
} }

View File

@ -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,
);
} }
/** 修改到货通知单行 */ /** 修改到货通知单行 */

View File

@ -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 },
},
);
} }
/** 批次向后追溯 */ /** 批次向后追溯 */

View File

@ -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,
});
} }

View File

@ -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 } },
);
} }
/** 查询外协发料单明细详情 */ /** 查询外协发料单明细详情 */

View File

@ -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 });
);
} }
/** 查询外协入库单详情 */ /** 查询外协入库单详情 */

View File

@ -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,
);
} }
/** 修改领料出库明细 */ /** 修改领料出库明细 */

View File

@ -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 });
);
} }
/** 查询领料出库单行详情 */ /** 查询领料出库单行详情 */

View File

@ -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,
);
} }
/** 修改销售出库明细 */ /** 修改销售出库明细 */

View File

@ -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,
);
} }
/** 修改供应商退货明细 */ /** 修改供应商退货明细 */

View File

@ -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 });
);
} }
/** 查询供应商退货单行详情 */ /** 查询供应商退货单行详情 */

View File

@ -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}`,
);
} }

View File

@ -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',

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;

View File

@ -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,
); );

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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,

View File

@ -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) &&

View File

@ -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),
'备注名称只能包含中文、英文字母、日文、数字和下划线_', '备注名称只能包含中文、英文字母、日文、数字和下划线_',

View File

@ -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;
}); });
/** 打开地图弹窗 */ /** 打开地图弹窗 */

View File

@ -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({

View File

@ -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> = {

View File

@ -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();

View File

@ -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

View File

@ -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="留空则事件发生即匹配"
/> />
<!-- 普通值输入 --> <!-- 普通值输入 -->

View File

@ -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,

View File

@ -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

View File

@ -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>

View File

@ -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' as const }], content: [
{ required: true, message: '请输入公告', trigger: 'blur' as const },
],
}; // }; //
</script> </script>

View File

@ -333,10 +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"
:list="libs"
/>
</Col> </Col>
<!-- 中心设计区域ComponentContainer --> <!-- 中心设计区域ComponentContainer -->
<Col :span="12"> <Col :span="12">

View File

@ -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;
} }

View File

@ -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>

View File

@ -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>

View File

@ -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"

View File

@ -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"

View File

@ -104,7 +104,12 @@ function getLunarInfo(day: string) {
termName, termName,
}; };
} catch { } catch {
return { lunarFestival: '', lunarText: '', solarFestival: '', termName: '' }; return {
lunarFestival: '',
lunarText: '',
solarFestival: '',
termName: '',
};
} }
} }

View File

@ -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,

View File

@ -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,

View File

@ -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: {

View File

@ -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 {

View File

@ -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',

View File

@ -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>

View File

@ -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;
} }

View File

@ -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>

View File

@ -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,

View File

@ -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'); //

View File

@ -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 }">

View File

@ -41,7 +41,7 @@ function getMultipleSelectedRows() {
] as MesDvCheckPlanApi.CheckPlan[]; ] as MesDvCheckPlanApi.CheckPlan[];
records.forEach((row) => { records.forEach((row) => {
const rowId = row.id; const rowId = row.id;
if (rowId != null) { if (rowId !== null) {
selectedMap.set(rowId, row); selectedMap.set(rowId, row);
} }
}); });
@ -66,7 +66,11 @@ async function toggleMultipleRow(row: MesDvCheckPlanApi.CheckPlan) {
} }
/** 处理行双击 */ /** 处理行双击 */
async function handleCellDblclick({ row }: { row: MesDvCheckPlanApi.CheckPlan }) { async function handleCellDblclick({
row,
}: {
row: MesDvCheckPlanApi.CheckPlan;
}) {
if (multiple.value) { if (multiple.value) {
await toggleMultipleRow(row); await toggleMultipleRow(row);
return; return;
@ -83,7 +87,7 @@ async function applyPreSelection() {
} }
const rows = getTableRows(); const rows = getTableRows();
for (const row of rows) { for (const row of rows) {
if (row.id == null || !preSelectedIds.value.includes(row.id)) { if (row.id === null || !preSelectedIds.value.includes(row.id)) {
continue; continue;
} }
if (multiple.value) { if (multiple.value) {

View File

@ -48,12 +48,12 @@ const showClear = computed(
props.allowClear && props.allowClear &&
!props.disabled && !props.disabled &&
hovering.value && hovering.value &&
props.modelValue != null, props.modelValue !== null,
); );
/** 根据方案编号回显选择器 */ /** 根据方案编号回显选择器 */
async function resolveItemById(id: number | undefined) { async function resolveItemById(id: number | undefined) {
if (id == null) { if (!id) {
selectedItem.value = undefined; selectedItem.value = undefined;
return; return;
} }
@ -89,7 +89,9 @@ function handleClick(event: MouseEvent) {
clearSelected(); clearSelected();
return; return;
} }
const selectedIds = props.modelValue == null ? [] : [props.modelValue]; const selectedIds = (
props.modelValue === null ? [] : [props.modelValue]
) as number[];
dialogRef.value?.open(selectedIds, { dialogRef.value?.open(selectedIds, {
multiple: false, multiple: false,
status: props.status, status: props.status,

View File

@ -4,7 +4,12 @@ import type { MesDvCheckPlanApi } from '#/api/mes/dv/checkplan';
import { h } from 'vue'; import { h } from 'vue';
import { DICT_TYPE, MesAutoCodeRuleCode, MesDvCheckPlanStatusEnum, MesDvSubjectTypeEnum } from '@vben/constants'; import {
DICT_TYPE,
MesAutoCodeRuleCode,
MesDvCheckPlanStatusEnum,
MesDvSubjectTypeEnum,
} 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';
@ -56,7 +61,9 @@ export function useFormSchema(
{ {
type: 'default', type: 'default',
onClick: async () => { onClick: async () => {
const code = await generateAutoCode(MesAutoCodeRuleCode.DV_CHECK_PLAN_CODE); const code = await generateAutoCode(
MesAutoCodeRuleCode.DV_CHECK_PLAN_CODE,
);
await formApi?.setFieldValue('code', code); await formApi?.setFieldValue('code', code);
}, },
}, },
@ -213,8 +220,18 @@ export function useGridColumns(): VxeTableGridOptions<MesDvCheckPlanApi.CheckPla
props: { type: DICT_TYPE.MES_DV_SUBJECT_TYPE }, props: { type: DICT_TYPE.MES_DV_SUBJECT_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: 'cycleType', field: 'cycleType',
title: '周期类型', title: '周期类型',
@ -234,7 +251,12 @@ export function useGridColumns(): VxeTableGridOptions<MesDvCheckPlanApi.CheckPla
props: { type: DICT_TYPE.MES_DV_CHECK_PLAN_STATUS }, props: { type: DICT_TYPE.MES_DV_CHECK_PLAN_STATUS },
}, },
}, },
{ field: 'createTime', title: '创建时间', width: 180, formatter: 'formatDateTime' }, {
field: 'createTime',
title: '创建时间',
width: 180,
formatter: 'formatDateTime',
},
{ {
title: '操作', title: '操作',
width: 240, width: 240,
@ -287,8 +309,18 @@ export function useCheckPlanSelectGridColumns(
props: { type: DICT_TYPE.MES_DV_SUBJECT_TYPE }, props: { type: DICT_TYPE.MES_DV_SUBJECT_TYPE },
}, },
}, },
{ field: 'startDate', title: '开始日期', width: 120, formatter: 'formatDate' }, {
{ field: 'endDate', title: '结束日期', width: 120, formatter: 'formatDate' }, field: 'startDate',
title: '开始日期',
width: 120,
formatter: 'formatDate',
},
{
field: 'endDate',
title: '结束日期',
width: 120,
formatter: 'formatDate',
},
{ field: 'cycleCount', title: '频率', width: 100 }, { field: 'cycleCount', title: '频率', width: 100 },
{ {
field: 'cycleType', field: 'cycleType',

View File

@ -11,7 +11,11 @@ import { MesDvCheckPlanStatusEnum } from '@vben/constants';
import { message, Tabs } from 'ant-design-vue'; import { message, Tabs } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form'; import { useVbenForm } from '#/adapter/form';
import { createCheckPlan, getCheckPlan, updateCheckPlan } from '#/api/mes/dv/checkplan'; import {
createCheckPlan,
getCheckPlan,
updateCheckPlan,
} from '#/api/mes/dv/checkplan';
import { $t } from '#/locales'; import { $t } from '#/locales';
import { useFormSchema } from '../data'; import { useFormSchema } from '../data';
@ -60,7 +64,11 @@ const [Modal, modalApi] = useVbenModal({
try { try {
if (formType.value === 'create') { if (formType.value === 'create') {
const id = await createCheckPlan(data); const id = await createCheckPlan(data);
formData.value = { ...data, id: id as number, status: MesDvCheckPlanStatusEnum.PREPARE }; formData.value = {
...data,
id: id as number,
status: MesDvCheckPlanStatusEnum.PREPARE,
};
await formApi.setFieldValue('id', id); await formApi.setFieldValue('id', id);
formType.value = 'update'; formType.value = 'update';
} else { } else {
@ -111,7 +119,11 @@ const [Modal, modalApi] = useVbenModal({
<MachineryList :form-type="formType" :plan-id="formData.id" /> <MachineryList :form-type="formType" :plan-id="formData.id" />
</Tabs.TabPane> </Tabs.TabPane>
<Tabs.TabPane key="subject" tab="项目"> <Tabs.TabPane key="subject" tab="项目">
<SubjectList :form-type="formType" :plan-id="formData.id" :plan-type="formData.type" /> <SubjectList
:form-type="formType"
:plan-id="formData.id"
:plan-type="formData.type"
/>
</Tabs.TabPane> </Tabs.TabPane>
</Tabs> </Tabs>
</Modal> </Modal>

View File

@ -159,7 +159,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 }">

View File

@ -171,7 +171,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 }">

View File

@ -4,7 +4,12 @@ import type { MesDvCheckRecordApi } from '#/api/mes/dv/checkrecord';
import { markRaw } from 'vue'; import { markRaw } from 'vue';
import { DICT_TYPE, MesDvCheckPlanStatusEnum, MesDvCheckRecordStatusEnum, MesDvSubjectTypeEnum } from '@vben/constants'; import {
DICT_TYPE,
MesDvCheckPlanStatusEnum,
MesDvCheckRecordStatusEnum,
MesDvSubjectTypeEnum,
} from '@vben/constants';
import { getDictOptions } from '@vben/hooks'; import { getDictOptions } from '@vben/hooks';
import { getSimpleUserList } from '#/api/system/user'; import { getSimpleUserList } from '#/api/system/user';
@ -137,7 +142,12 @@ export function useGridColumns(): VxeTableGridOptions<MesDvCheckRecordApi.CheckR
}, },
}, },
{ field: 'planName', title: '计划名称', minWidth: 150 }, { field: 'planName', title: '计划名称', minWidth: 150 },
{ field: 'checkTime', title: '点检时间', width: 180, formatter: 'formatDateTime' }, {
field: 'checkTime',
title: '点检时间',
width: 180,
formatter: 'formatDateTime',
},
{ field: 'nickname', title: '点检人', minWidth: 120 }, { field: 'nickname', title: '点检人', minWidth: 120 },
{ {
field: 'status', field: 'status',
@ -148,7 +158,12 @@ export function useGridColumns(): VxeTableGridOptions<MesDvCheckRecordApi.CheckR
props: { type: DICT_TYPE.MES_DV_CHECK_RECORD_STATUS }, props: { type: DICT_TYPE.MES_DV_CHECK_RECORD_STATUS },
}, },
}, },
{ field: 'createTime', title: '创建时间', width: 180, formatter: 'formatDateTime' }, {
field: 'createTime',
title: '创建时间',
width: 180,
formatter: 'formatDateTime',
},
{ {
title: '操作', title: '操作',
width: 200, width: 200,

View File

@ -9,7 +9,11 @@ import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message } from 'ant-design-vue'; import { Button, message } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteCheckRecord, exportCheckRecord, getCheckRecordPage } from '#/api/mes/dv/checkrecord'; import {
deleteCheckRecord,
exportCheckRecord,
getCheckRecordPage,
} from '#/api/mes/dv/checkrecord';
import { $t } from '#/locales'; import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data'; import { useGridColumns, useGridFormSchema } from './data';
@ -121,7 +125,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
/> />
</template> </template>
<template #machineryName="{ row }"> <template #machineryName="{ row }">
<Button type="link" @click="handleDetail(row)">{{ row.machineryName }}</Button> <Button type="link" @click="handleDetail(row)">
{{ row.machineryName }}
</Button>
</template> </template>
<template #actions="{ row }"> <template #actions="{ row }">
<TableAction <TableAction
@ -141,7 +147,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
icon: ACTION_ICON.DELETE, icon: ACTION_ICON.DELETE,
auth: ['mes:dv-check-record:delete'], auth: ['mes:dv-check-record:delete'],
popConfirm: { popConfirm: {
title: $t('ui.actionMessage.deleteConfirm', [row.machineryName]), title: $t('ui.actionMessage.deleteConfirm', [
row.machineryName,
]),
confirm: handleDelete.bind(null, row), confirm: handleDelete.bind(null, row),
}, },
ifShow: row.status === MesDvCheckRecordStatusEnum.DRAFT, ifShow: row.status === MesDvCheckRecordStatusEnum.DRAFT,

View File

@ -27,7 +27,9 @@ const formType = ref<FormType>('create');
const formData = ref<MesDvCheckRecordApi.CheckRecord>(); const formData = ref<MesDvCheckRecordApi.CheckRecord>();
const isDetail = computed(() => formType.value === 'detail'); const isDetail = computed(() => formType.value === 'detail');
const canSubmit = computed( const canSubmit = computed(
() => formType.value === 'update' && formData.value?.status === MesDvCheckRecordStatusEnum.DRAFT, () =>
formType.value === 'update' &&
formData.value?.status === MesDvCheckRecordStatusEnum.DRAFT,
); );
const getTitle = computed(() => { const getTitle = computed(() => {
if (formType.value === 'detail') { if (formType.value === 'detail') {
@ -59,7 +61,9 @@ async function handleSubmit() {
modalApi.lock(); modalApi.lock();
try { try {
await updateCheckRecord((await formApi.getValues()) as MesDvCheckRecordApi.CheckRecord); await updateCheckRecord(
(await formApi.getValues()) as MesDvCheckRecordApi.CheckRecord,
);
await submitCheckRecord(formData.value.id); await submitCheckRecord(formData.value.id);
await modalApi.close(); await modalApi.close();
emit('success'); emit('success');
@ -85,7 +89,11 @@ const [Modal, modalApi] = useVbenModal({
try { try {
if (formType.value === 'create') { if (formType.value === 'create') {
const id = await createCheckRecord(data); const id = await createCheckRecord(data);
formData.value = { ...data, id: id as number, status: MesDvCheckRecordStatusEnum.DRAFT }; formData.value = {
...data,
id: id as number,
status: MesDvCheckRecordStatusEnum.DRAFT,
};
await formApi.setFieldValue('id', id); await formApi.setFieldValue('id', id);
formType.value = 'update'; formType.value = 'update';
} else { } else {
@ -125,7 +133,11 @@ const [Modal, modalApi] = useVbenModal({
<template> <template>
<Modal :title="getTitle" class="w-4/5"> <Modal :title="getTitle" class="w-4/5">
<Form class="mx-4" /> <Form class="mx-4" />
<LineList v-if="formData?.id" :disabled="isDetail" :record-id="formData.id" /> <LineList
v-if="formData?.id"
:disabled="isDetail"
:record-id="formData.id"
/>
<template #prepend-footer> <template #prepend-footer>
<div class="flex flex-auto items-center"> <div class="flex flex-auto items-center">
<Popconfirm <Popconfirm

View File

@ -4,7 +4,11 @@ import type { MesDvCheckRecordLineApi } from '#/api/mes/dv/checkrecord/line';
import { computed, ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
import { DICT_TYPE, MesDvCheckResultEnum, MesDvSubjectTypeEnum } from '@vben/constants'; import {
DICT_TYPE,
MesDvCheckResultEnum,
MesDvSubjectTypeEnum,
} from '@vben/constants';
import { getDictOptions } from '@vben/hooks'; import { getDictOptions } from '@vben/hooks';
import { message, Modal } from 'ant-design-vue'; import { message, Modal } from 'ant-design-vue';
@ -25,7 +29,9 @@ const props = defineProps<{ disabled?: boolean; recordId: number }>();
const formOpen = ref(false); const formOpen = ref(false);
const formLoading = ref(false); const formLoading = ref(false);
const lineFormType = ref<'create' | 'update'>('create'); const lineFormType = ref<'create' | 'update'>('create');
const formTitle = computed(() => (lineFormType.value === 'create' ? '添加明细' : '修改明细')); const formTitle = computed(() =>
lineFormType.value === 'create' ? '添加明细' : '修改明细',
);
const [Form, formApi] = useVbenForm({ const [Form, formApi] = useVbenForm({
commonConfig: { commonConfig: {
@ -144,7 +150,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
}); });
/** 打开点检明细表单 */ /** 打开点检明细表单 */
async function openForm(type: 'create' | 'update', row?: MesDvCheckRecordLineApi.CheckRecordLine) { async function openForm(
type: 'create' | 'update',
row?: MesDvCheckRecordLineApi.CheckRecordLine,
) {
formOpen.value = true; formOpen.value = true;
lineFormType.value = type; lineFormType.value = type;
await formApi.resetForm(); await formApi.resetForm();
@ -168,7 +177,8 @@ async function submitForm() {
} }
formLoading.value = true; formLoading.value = true;
try { try {
const data = (await formApi.getValues()) as MesDvCheckRecordLineApi.CheckRecordLine; const data =
(await formApi.getValues()) as MesDvCheckRecordLineApi.CheckRecordLine;
await (data.id ? updateCheckRecordLine(data) : createCheckRecordLine(data)); await (data.id ? updateCheckRecordLine(data) : createCheckRecordLine(data));
formOpen.value = false; formOpen.value = false;
message.success($t('ui.actionMessage.operationSuccess')); message.success($t('ui.actionMessage.operationSuccess'));
@ -197,14 +207,24 @@ watch(
<div class="mx-4 mt-4"> <div class="mx-4 mt-4">
<div v-if="!disabled" class="mb-3"> <div v-if="!disabled" class="mb-3">
<TableAction <TableAction
:actions="[{ label: '添加明细', type: 'primary', onClick: openForm.bind(null, 'create') }]" :actions="[
{
label: '添加明细',
type: 'primary',
onClick: openForm.bind(null, 'create'),
},
]"
/> />
</div> </div>
<Grid table-title=""> <Grid table-title="">
<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',

View File

@ -43,7 +43,7 @@ function getMultipleSelectedRows() {
] as MesDvMachineryApi.Machinery[]; ] as MesDvMachineryApi.Machinery[];
records.forEach((row) => { records.forEach((row) => {
const rowId = row.id; const rowId = row.id;
if (rowId != null) { if (rowId !== null) {
selectedMap.set(rowId, row); selectedMap.set(rowId, row);
} }
}); });
@ -68,7 +68,11 @@ async function toggleMultipleRow(row: MesDvMachineryApi.Machinery) {
} }
/** 处理行双击 */ /** 处理行双击 */
async function handleCellDblclick({ row }: { row: MesDvMachineryApi.Machinery }) { async function handleCellDblclick({
row,
}: {
row: MesDvMachineryApi.Machinery;
}) {
if (multiple.value) { if (multiple.value) {
await toggleMultipleRow(row); await toggleMultipleRow(row);
return; return;
@ -79,7 +83,9 @@ async function handleCellDblclick({ row }: { row: MesDvMachineryApi.Machinery })
} }
/** 按设备类型筛选 */ /** 按设备类型筛选 */
function handleTypeNodeClick(row: MesDvMachineryTypeApi.MachineryType | undefined) { function handleTypeNodeClick(
row: MesDvMachineryTypeApi.MachineryType | undefined,
) {
selectedMachineryTypeId.value = row?.id; selectedMachineryTypeId.value = row?.id;
gridApi.query(); gridApi.query();
} }
@ -91,7 +97,7 @@ async function applyPreSelection() {
} }
const rows = getTableRows(); const rows = getTableRows();
for (const row of rows) { for (const row of rows) {
if (row.id == null || !preSelectedIds.value.includes(row.id)) { if (row.id === null || !preSelectedIds.value.includes(row.id)) {
continue; continue;
} }
if (multiple.value) { if (multiple.value) {
@ -215,7 +221,10 @@ defineExpose({ open: openModal });
> >
<div class="flex h-full w-full"> <div class="flex h-full w-full">
<div class="mr-4 h-full w-1/5"> <div class="mr-4 h-full w-1/5">
<MachineryTypeTree ref="typeTreeRef" @node-click="handleTypeNodeClick" /> <MachineryTypeTree
ref="typeTreeRef"
@node-click="handleTypeNodeClick"
/>
</div> </div>
<div class="w-4/5"> <div class="w-4/5">
<Grid table-title="" /> <Grid table-title="" />

View File

@ -42,12 +42,12 @@ const showClear = computed(
props.allowClear && props.allowClear &&
!props.disabled && !props.disabled &&
hovering.value && hovering.value &&
props.modelValue != null, props.modelValue !== null,
); );
/** 根据设备编号回显选择器 */ /** 根据设备编号回显选择器 */
async function resolveItemById(id: number | undefined) { async function resolveItemById(id: number | undefined) {
if (id == null) { if (!id) {
selectedItem.value = undefined; selectedItem.value = undefined;
return; return;
} }
@ -83,7 +83,9 @@ function handleClick(event: MouseEvent) {
clearSelected(); clearSelected();
return; return;
} }
const selectedIds = props.modelValue == null ? [] : [props.modelValue]; const selectedIds = (
props.modelValue === null ? [] : [props.modelValue]
) as number[];
dialogRef.value?.open(selectedIds, { multiple: false }); dialogRef.value?.open(selectedIds, { multiple: false });
} }

View File

@ -4,7 +4,11 @@ import type { MesDvMachineryApi } from '#/api/mes/dv/machinery';
import { h, markRaw } from 'vue'; import { h, markRaw } from 'vue';
import { DICT_TYPE, MesAutoCodeRuleCode, MesDvMachineryStatusEnum } from '@vben/constants'; import {
DICT_TYPE,
MesAutoCodeRuleCode,
MesDvMachineryStatusEnum,
} 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';
@ -19,7 +23,10 @@ import { DvMachineryTypeSelect } from './type/components';
export type FormType = 'create' | 'detail' | 'update'; export type FormType = 'create' | 'detail' | 'update';
/** 新增/修改设备的表单 */ /** 新增/修改设备的表单 */
export function useFormSchema(formType: FormType, formApi?: VbenFormApi): VbenFormSchema[] { export function useFormSchema(
formType: FormType,
formApi?: VbenFormApi,
): VbenFormSchema[] {
return [ return [
{ {
fieldName: 'id', fieldName: 'id',
@ -50,7 +57,9 @@ export function useFormSchema(formType: FormType, formApi?: VbenFormApi): VbenFo
{ {
type: 'default', type: 'default',
onClick: async () => { onClick: async () => {
const code = await generateAutoCode(MesAutoCodeRuleCode.DV_MACHINERY_CODE); const code = await generateAutoCode(
MesAutoCodeRuleCode.DV_MACHINERY_CODE,
);
await formApi?.setFieldValue('code', code); await formApi?.setFieldValue('code', code);
}, },
}, },

View File

@ -11,7 +11,11 @@ import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message } from 'ant-design-vue'; import { Button, message } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteMachinery, exportMachinery, getMachineryPage } from '#/api/mes/dv/machinery'; import {
deleteMachinery,
exportMachinery,
getMachineryPage,
} from '#/api/mes/dv/machinery';
import { $t } from '#/locales'; import { $t } from '#/locales';
import { MachineryTypeTree } from '#/views/mes/dv/machinery/type/components'; import { MachineryTypeTree } from '#/views/mes/dv/machinery/type/components';
@ -77,7 +81,9 @@ function handleImport() {
} }
/** 按设备类型筛选 */ /** 按设备类型筛选 */
function handleTypeNodeClick(row: MesDvMachineryTypeApi.MachineryType | undefined) { function handleTypeNodeClick(
row: MesDvMachineryTypeApi.MachineryType | undefined,
) {
selectedMachineryTypeId.value = row?.id; selectedMachineryTypeId.value = row?.id;
handleRefresh(); handleRefresh();
} }
@ -157,7 +163,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
/> />
</template> </template>
<template #code="{ row }"> <template #code="{ row }">
<Button type="link" @click="handleDetail(row)">{{ row.code }}</Button> <Button type="link" @click="handleDetail(row)">
{{ row.code }}
</Button>
</template> </template>
<template #actions="{ row }"> <template #actions="{ row }">
<TableAction <TableAction

View File

@ -24,7 +24,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
props: { type: DICT_TYPE.MES_DV_CYCLE_TYPE }, props: { type: DICT_TYPE.MES_DV_CYCLE_TYPE },
}, },
}, },
{ field: 'checkTime', title: '点检时间', width: 180, formatter: 'formatDateTime' }, {
field: 'checkTime',
title: '点检时间',
width: 180,
formatter: 'formatDateTime',
},
{ field: 'nickname', title: '操作人', minWidth: 120 }, { field: 'nickname', title: '操作人', minWidth: 120 },
{ {
field: 'status', field: 'status',

View File

@ -11,7 +11,11 @@ import { BarcodeBizTypeEnum } from '@vben/constants';
import { Button, message, Tabs } from 'ant-design-vue'; import { Button, message, Tabs } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form'; import { useVbenForm } from '#/adapter/form';
import { createMachinery, getMachinery, updateMachinery } from '#/api/mes/dv/machinery'; import {
createMachinery,
getMachinery,
updateMachinery,
} from '#/api/mes/dv/machinery';
import { $t } from '#/locales'; import { $t } from '#/locales';
import { BarcodeDetail } from '#/views/mes/wm/barcode/components'; import { BarcodeDetail } from '#/views/mes/wm/barcode/components';
@ -130,7 +134,11 @@ const [Modal, modalApi] = useVbenModal({
</Tabs> </Tabs>
<template #prepend-footer> <template #prepend-footer>
<div class="flex flex-auto items-center"> <div class="flex flex-auto items-center">
<Button v-if="isDetail && formData?.id" type="primary" @click="handleBarcode"> <Button
v-if="isDetail && formData?.id"
type="primary"
@click="handleBarcode"
>
查看条码 查看条码
</Button> </Button>
</div> </div>

View File

@ -9,7 +9,10 @@ import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message, Upload } from 'ant-design-vue'; import { Button, message, Upload } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form'; import { useVbenForm } from '#/adapter/form';
import { importMachinery, importMachineryTemplate } from '#/api/mes/dv/machinery'; import {
importMachinery,
importMachineryTemplate,
} from '#/api/mes/dv/machinery';
import { $t } from '#/locales'; import { $t } from '#/locales';
import { useImportFormSchema } from '../data'; import { useImportFormSchema } from '../data';
@ -73,7 +76,11 @@ async function handleDownload() {
<Form class="mx-4"> <Form class="mx-4">
<template #file> <template #file>
<div class="w-full"> <div class="w-full">
<Upload :before-upload="beforeUpload" :max-count="1" accept=".xls,.xlsx"> <Upload
:before-upload="beforeUpload"
:max-count="1"
accept=".xls,.xlsx"
>
<Button type="primary">选择 Excel 文件</Button> <Button type="primary">选择 Excel 文件</Button>
</Upload> </Upload>
</div> </div>

View File

@ -24,7 +24,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
props: { type: DICT_TYPE.MES_DV_CYCLE_TYPE }, props: { type: DICT_TYPE.MES_DV_CYCLE_TYPE },
}, },
}, },
{ field: 'maintenTime', title: '保养时间', width: 180, formatter: 'formatDateTime' }, {
field: 'maintenTime',
title: '保养时间',
width: 180,
formatter: 'formatDateTime',
},
{ field: 'nickname', title: '操作人', minWidth: 120 }, { field: 'nickname', title: '操作人', minWidth: 120 },
{ {
field: 'status', field: 'status',

View File

@ -25,7 +25,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
props: { type: DICT_TYPE.MES_DV_REPAIR_RESULT }, props: { type: DICT_TYPE.MES_DV_REPAIR_RESULT },
}, },
}, },
{ field: 'requireDate', title: '报修日期', width: 180, formatter: 'formatDateTime' }, {
field: 'requireDate',
title: '报修日期',
width: 180,
formatter: 'formatDateTime',
},
{ field: 'nickname', title: '操作人', minWidth: 120 }, { field: 'nickname', title: '操作人', minWidth: 120 },
{ {
field: 'status', field: 'status',

View File

@ -47,9 +47,13 @@ const selectValue = computed({
}); });
/** 递归将有子节点的分支节点标记为 disabled */ /** 递归将有子节点的分支节点标记为 disabled */
function markParentsDisabled(nodes: MesDvMachineryTypeApi.MachineryType[]): MachineryTypeNode[] { function markParentsDisabled(
nodes: MesDvMachineryTypeApi.MachineryType[],
): MachineryTypeNode[] {
return nodes.map((node) => { return nodes.map((node) => {
const children = node.children?.length ? markParentsDisabled(node.children) : undefined; const children = node.children?.length
? markParentsDisabled(node.children)
: undefined;
return { ...node, children, disabled: Boolean(children?.length) }; return { ...node, children, disabled: Boolean(children?.length) };
}); });
} }
@ -57,7 +61,9 @@ function markParentsDisabled(nodes: MesDvMachineryTypeApi.MachineryType[]): Mach
/** 根据当前值同步 tooltip 展示的设备类型详情 */ /** 根据当前值同步 tooltip 展示的设备类型详情 */
function syncSelectedItem(value: number | undefined) { function syncSelectedItem(value: number | undefined) {
selectedItem.value = selectedItem.value =
value === undefined ? undefined : allList.value.find((item) => item.id === value); value === undefined
? undefined
: allList.value.find((item) => item.id === value);
} }
/** 除 v-model 外,额外抛出完整设备类型对象给业务表单使用 */ /** 除 v-model 外,额外抛出完整设备类型对象给业务表单使用 */

View File

@ -4,7 +4,11 @@ import type { MesDvMachineryTypeApi } from '#/api/mes/dv/machinery/type';
import { h } from 'vue'; import { h } from 'vue';
import { CommonStatusEnum, DICT_TYPE, MesAutoCodeRuleCode } from '@vben/constants'; import {
CommonStatusEnum,
DICT_TYPE,
MesAutoCodeRuleCode,
} from '@vben/constants';
import { getDictOptions } from '@vben/hooks'; import { getDictOptions } from '@vben/hooks';
import { handleTree } from '@vben/utils'; import { handleTree } from '@vben/utils';
@ -38,7 +42,11 @@ export function useFormSchema(
componentProps: { componentProps: {
allowClear: true, allowClear: true,
api: async () => [ api: async () => [
{ id: 0, name: '顶级类型', children: handleTree(await getMachineryTypeList()) }, {
id: 0,
name: '顶级类型',
children: handleTree(await getMachineryTypeList()),
},
], ],
childrenField: 'children', childrenField: 'children',
labelField: 'name', labelField: 'name',
@ -147,7 +155,13 @@ export function useGridFormSchema(): VbenFormSchema[] {
/** 列表的字段 */ /** 列表的字段 */
export function useGridColumns(): VxeTableGridOptions<MesDvMachineryTypeApi.MachineryType>['columns'] { export function useGridColumns(): VxeTableGridOptions<MesDvMachineryTypeApi.MachineryType>['columns'] {
return [ return [
{ field: 'name', title: '类型名称', minWidth: 200, align: 'left', treeNode: true }, {
field: 'name',
title: '类型名称',
minWidth: 200,
align: 'left',
treeNode: true,
},
{ field: 'code', title: '类型编码', width: 160, align: 'center' }, { field: 'code', title: '类型编码', width: 160, align: 'center' },
{ field: 'sort', title: '排序', width: 100, align: 'center' }, { field: 'sort', title: '排序', width: 100, align: 'center' },
{ {

View File

@ -10,7 +10,10 @@ import { handleTree } from '@vben/utils';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteMachineryType, getMachineryTypeList } from '#/api/mes/dv/machinery/type'; import {
deleteMachineryType,
getMachineryTypeList,
} from '#/api/mes/dv/machinery/type';
import { $t } from '#/locales'; import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data'; import { useGridColumns, useGridFormSchema } from './data';
@ -76,7 +79,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
enabled: false, enabled: false,
}, },
proxyConfig: { proxyConfig: {
ajax: { query: async (_, formValues) => handleTree(await getMachineryTypeList(formValues)) }, ajax: {
query: async (_, formValues) =>
handleTree(await getMachineryTypeList(formValues)),
},
}, },
rowConfig: { rowConfig: {
keyField: 'id', keyField: 'id',

View File

@ -46,7 +46,8 @@ const [Modal, modalApi] = useVbenModal({
} }
modalApi.lock(); modalApi.lock();
// //
const data = (await formApi.getValues()) as MesDvMachineryTypeApi.MachineryType; const data =
(await formApi.getValues()) as MesDvMachineryTypeApi.MachineryType;
try { try {
await (formData.value?.id await (formData.value?.id
? updateMachineryType(data) ? updateMachineryType(data)

View File

@ -4,7 +4,12 @@ import type { MesDvMaintenRecordApi } from '#/api/mes/dv/maintenrecord';
import { markRaw } from 'vue'; import { markRaw } from 'vue';
import { DICT_TYPE, MesDvCheckPlanStatusEnum, MesDvMaintenRecordStatusEnum, MesDvSubjectTypeEnum } from '@vben/constants'; import {
DICT_TYPE,
MesDvCheckPlanStatusEnum,
MesDvMaintenRecordStatusEnum,
MesDvSubjectTypeEnum,
} from '@vben/constants';
import { getDictOptions } from '@vben/hooks'; import { getDictOptions } from '@vben/hooks';
import { getSimpleUserList } from '#/api/system/user'; import { getSimpleUserList } from '#/api/system/user';
@ -137,7 +142,12 @@ export function useGridColumns(): VxeTableGridOptions<MesDvMaintenRecordApi.Main
}, },
}, },
{ field: 'planName', title: '计划名称', minWidth: 150 }, { field: 'planName', title: '计划名称', minWidth: 150 },
{ field: 'maintenTime', title: '保养时间', width: 180, formatter: 'formatDateTime' }, {
field: 'maintenTime',
title: '保养时间',
width: 180,
formatter: 'formatDateTime',
},
{ field: 'nickname', title: '保养人', minWidth: 120 }, { field: 'nickname', title: '保养人', minWidth: 120 },
{ {
field: 'status', field: 'status',
@ -148,7 +158,12 @@ export function useGridColumns(): VxeTableGridOptions<MesDvMaintenRecordApi.Main
props: { type: DICT_TYPE.MES_MAINTEN_RECORD_STATUS }, props: { type: DICT_TYPE.MES_MAINTEN_RECORD_STATUS },
}, },
}, },
{ field: 'createTime', title: '创建时间', width: 180, formatter: 'formatDateTime' }, {
field: 'createTime',
title: '创建时间',
width: 180,
formatter: 'formatDateTime',
},
{ {
title: '操作', title: '操作',
width: 200, width: 200,

View File

@ -125,7 +125,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
/> />
</template> </template>
<template #machineryName="{ row }"> <template #machineryName="{ row }">
<Button type="link" @click="handleDetail(row)">{{ row.machineryName }}</Button> <Button type="link" @click="handleDetail(row)">
{{ row.machineryName }}
</Button>
</template> </template>
<template #actions="{ row }"> <template #actions="{ row }">
<TableAction <TableAction
@ -145,7 +147,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
icon: ACTION_ICON.DELETE, icon: ACTION_ICON.DELETE,
auth: ['mes:dv-mainten-record:delete'], auth: ['mes:dv-mainten-record:delete'],
popConfirm: { popConfirm: {
title: $t('ui.actionMessage.deleteConfirm', [row.machineryName]), title: $t('ui.actionMessage.deleteConfirm', [
row.machineryName,
]),
confirm: handleDelete.bind(null, row), confirm: handleDelete.bind(null, row),
}, },
ifShow: row.status === MesDvMaintenRecordStatusEnum.PREPARE, ifShow: row.status === MesDvMaintenRecordStatusEnum.PREPARE,

View File

@ -30,7 +30,8 @@ const formData = ref<MesDvMaintenRecordApi.MaintenRecord>();
const isDetail = computed(() => formType.value === 'detail'); const isDetail = computed(() => formType.value === 'detail');
const canSubmit = computed( const canSubmit = computed(
() => () =>
formType.value === 'update' && formData.value?.status === MesDvMaintenRecordStatusEnum.PREPARE, formType.value === 'update' &&
formData.value?.status === MesDvMaintenRecordStatusEnum.PREPARE,
); );
const getTitle = computed(() => { const getTitle = computed(() => {
if (formType.value === 'detail') { if (formType.value === 'detail') {
@ -62,7 +63,9 @@ async function handleSubmit() {
modalApi.lock(); modalApi.lock();
try { try {
await updateMaintenRecord((await formApi.getValues()) as MesDvMaintenRecordApi.MaintenRecord); await updateMaintenRecord(
(await formApi.getValues()) as MesDvMaintenRecordApi.MaintenRecord,
);
await submitMaintenRecord(formData.value.id); await submitMaintenRecord(formData.value.id);
await modalApi.close(); await modalApi.close();
emit('success'); emit('success');
@ -84,7 +87,8 @@ const [Modal, modalApi] = useVbenModal({
} }
modalApi.lock(); modalApi.lock();
// //
const data = (await formApi.getValues()) as MesDvMaintenRecordApi.MaintenRecord; const data =
(await formApi.getValues()) as MesDvMaintenRecordApi.MaintenRecord;
try { try {
if (formType.value === 'create') { if (formType.value === 'create') {
const id = await createMaintenRecord(data); const id = await createMaintenRecord(data);
@ -133,7 +137,11 @@ const [Modal, modalApi] = useVbenModal({
<template> <template>
<Modal :title="getTitle" class="w-4/5"> <Modal :title="getTitle" class="w-4/5">
<Form class="mx-4" /> <Form class="mx-4" />
<LineList v-if="formData?.id" :disabled="isDetail" :record-id="formData.id" /> <LineList
v-if="formData?.id"
:disabled="isDetail"
:record-id="formData.id"
/>
<template #prepend-footer> <template #prepend-footer>
<div class="flex flex-auto items-center"> <div class="flex flex-auto items-center">
<Popconfirm <Popconfirm

View File

@ -4,7 +4,11 @@ import type { MesDvMaintenRecordLineApi } from '#/api/mes/dv/maintenrecord/line'
import { computed, ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
import { DICT_TYPE, MesDvMaintenStatusEnum, MesDvSubjectTypeEnum } from '@vben/constants'; import {
DICT_TYPE,
MesDvMaintenStatusEnum,
MesDvSubjectTypeEnum,
} from '@vben/constants';
import { getDictOptions } from '@vben/hooks'; import { getDictOptions } from '@vben/hooks';
import { message, Modal } from 'ant-design-vue'; import { message, Modal } from 'ant-design-vue';
@ -25,7 +29,9 @@ const props = defineProps<{ disabled?: boolean; recordId: number }>();
const formOpen = ref(false); const formOpen = ref(false);
const formLoading = ref(false); const formLoading = ref(false);
const lineFormType = ref<'create' | 'update'>('create'); const lineFormType = ref<'create' | 'update'>('create');
const formTitle = computed(() => (lineFormType.value === 'create' ? '添加明细' : '修改明细')); const formTitle = computed(() =>
lineFormType.value === 'create' ? '添加明细' : '修改明细',
);
const [Form, formApi] = useVbenForm({ const [Form, formApi] = useVbenForm({
commonConfig: { commonConfig: {
@ -171,8 +177,11 @@ async function submitForm() {
} }
formLoading.value = true; formLoading.value = true;
try { try {
const data = (await formApi.getValues()) as MesDvMaintenRecordLineApi.MaintenRecordLine; const data =
await (data.id ? updateMaintenRecordLine(data) : createMaintenRecordLine(data)); (await formApi.getValues()) as MesDvMaintenRecordLineApi.MaintenRecordLine;
await (data.id
? updateMaintenRecordLine(data)
: createMaintenRecordLine(data));
formOpen.value = false; formOpen.value = false;
message.success($t('ui.actionMessage.operationSuccess')); message.success($t('ui.actionMessage.operationSuccess'));
await gridApi.query(); await gridApi.query();
@ -200,14 +209,24 @@ watch(
<div class="mx-4 mt-4"> <div class="mx-4 mt-4">
<div v-if="!disabled" class="mb-3"> <div v-if="!disabled" class="mb-3">
<TableAction <TableAction
:actions="[{ label: '添加明细', type: 'primary', onClick: openForm.bind(null, 'create') }]" :actions="[
{
label: '添加明细',
type: 'primary',
onClick: openForm.bind(null, 'create'),
},
]"
/> />
</div> </div>
<Grid table-title=""> <Grid table-title="">
<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',

View File

@ -4,7 +4,11 @@ import type { MesDvRepairApi } from '#/api/mes/dv/repair';
import { h, markRaw } from 'vue'; import { h, markRaw } from 'vue';
import { DICT_TYPE, MesAutoCodeRuleCode, MesDvRepairStatusEnum } from '@vben/constants'; import {
DICT_TYPE,
MesAutoCodeRuleCode,
MesDvRepairStatusEnum,
} 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';
@ -54,7 +58,9 @@ export function useFormSchema(
}, },
dependencies: { dependencies: {
triggerFields: ['id'], triggerFields: ['id'],
componentProps: (values) => ({ disabled: headerReadonly || !!values.id }), componentProps: (values) => ({
disabled: headerReadonly || !!values.id,
}),
}, },
rules: 'required', rules: 'required',
suffix: headerReadonly suffix: headerReadonly
@ -65,7 +71,9 @@ export function useFormSchema(
{ {
type: 'default', type: 'default',
onClick: async () => { onClick: async () => {
const code = await generateAutoCode(MesAutoCodeRuleCode.DV_REPAIR_CODE); const code = await generateAutoCode(
MesAutoCodeRuleCode.DV_REPAIR_CODE,
);
await formApi?.setFieldValue('code', code); await formApi?.setFieldValue('code', code);
}, },
}, },
@ -121,7 +129,7 @@ export function useFormSchema(
dependencies: { dependencies: {
triggerFields: ['status'], triggerFields: ['status'],
if: (values) => if: (values) =>
values.status != null && values.status !== null &&
values.status >= MesDvRepairStatusEnum.APPROVING, values.status >= MesDvRepairStatusEnum.APPROVING,
}, },
}, },
@ -139,7 +147,7 @@ export function useFormSchema(
dependencies: { dependencies: {
triggerFields: ['status'], triggerFields: ['status'],
if: (values) => if: (values) =>
values.status != null && values.status !== null &&
values.status >= MesDvRepairStatusEnum.CONFIRMED, values.status >= MesDvRepairStatusEnum.CONFIRMED,
disabled: formType !== 'confirm', disabled: formType !== 'confirm',
rules: () => (formType === 'confirm' ? 'required' : null), rules: () => (formType === 'confirm' ? 'required' : null),
@ -161,7 +169,7 @@ export function useFormSchema(
dependencies: { dependencies: {
triggerFields: ['status'], triggerFields: ['status'],
if: (values) => if: (values) =>
values.status != null && values.status !== null &&
values.status >= MesDvRepairStatusEnum.FINISHED, values.status >= MesDvRepairStatusEnum.FINISHED,
}, },
}, },
@ -180,7 +188,7 @@ export function useFormSchema(
dependencies: { dependencies: {
triggerFields: ['status'], triggerFields: ['status'],
if: (values) => if: (values) =>
values.status != null && values.status !== null &&
values.status >= MesDvRepairStatusEnum.FINISHED, values.status >= MesDvRepairStatusEnum.FINISHED,
}, },
}, },
@ -198,7 +206,7 @@ export function useFormSchema(
dependencies: { dependencies: {
triggerFields: ['status'], triggerFields: ['status'],
if: (values) => if: (values) =>
values.status != null && values.status !== null &&
values.status >= MesDvRepairStatusEnum.FINISHED, values.status >= MesDvRepairStatusEnum.FINISHED,
}, },
}, },
@ -288,8 +296,18 @@ export function useGridColumns(): VxeTableGridOptions<MesDvRepairApi.Repair>['co
}, },
{ field: 'name', title: '维修单名称', minWidth: 150 }, { field: 'name', title: '维修单名称', minWidth: 150 },
{ field: 'machineryName', title: '设备名称', minWidth: 150 }, { field: 'machineryName', title: '设备名称', minWidth: 150 },
{ field: 'requireDate', title: '报修日期', width: 180, formatter: 'formatDateTime' }, {
{ field: 'finishDate', title: '完成日期', width: 180, formatter: 'formatDateTime' }, field: 'requireDate',
title: '报修日期',
width: 180,
formatter: 'formatDateTime',
},
{
field: 'finishDate',
title: '完成日期',
width: 180,
formatter: 'formatDateTime',
},
{ {
field: 'result', field: 'result',
title: '维修结果', title: '维修结果',
@ -308,7 +326,12 @@ export function useGridColumns(): VxeTableGridOptions<MesDvRepairApi.Repair>['co
props: { type: DICT_TYPE.MES_DV_REPAIR_STATUS }, props: { type: DICT_TYPE.MES_DV_REPAIR_STATUS },
}, },
}, },
{ field: 'createTime', title: '创建时间', width: 180, formatter: 'formatDateTime' }, {
field: 'createTime',
title: '创建时间',
width: 180,
formatter: 'formatDateTime',
},
{ {
title: '操作', title: '操作',
width: 260, width: 260,

View File

@ -82,7 +82,11 @@ const [Grid, gridApi] = useVbenVxeGrid({
proxyConfig: { proxyConfig: {
ajax: { ajax: {
query: async ({ page }, formValues) => query: async ({ page }, formValues) =>
await getRepairPage({ pageNo: page.currentPage, pageSize: page.pageSize, ...formValues }), await getRepairPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
...formValues,
}),
}, },
}, },
rowConfig: { rowConfig: {

View File

@ -37,7 +37,9 @@ const isFormDisabled = computed(() =>
['detail', 'finish'].includes(formType.value), ['detail', 'finish'].includes(formType.value),
); );
const canSubmit = computed( const canSubmit = computed(
() => formType.value === 'update' && formData.value?.status === MesDvRepairStatusEnum.PREPARE, () =>
formType.value === 'update' &&
formData.value?.status === MesDvRepairStatusEnum.PREPARE,
); );
const getTitle = computed(() => { const getTitle = computed(() => {
if (formType.value === 'detail') { if (formType.value === 'detail') {
@ -138,7 +140,11 @@ async function doFinish(result: number) {
const [Modal, modalApi] = useVbenModal({ const [Modal, modalApi] = useVbenModal({
async onConfirm() { async onConfirm() {
if (isDetail.value || formType.value === 'confirm' || formType.value === 'finish') { if (
isDetail.value ||
formType.value === 'confirm' ||
formType.value === 'finish'
) {
await modalApi.close(); await modalApi.close();
return; return;
} }
@ -152,7 +158,11 @@ const [Modal, modalApi] = useVbenModal({
try { try {
if (formType.value === 'create') { if (formType.value === 'create') {
const id = await createRepair(data); const id = await createRepair(data);
formData.value = { ...data, id: id as number, status: MesDvRepairStatusEnum.PREPARE }; formData.value = {
...data,
id: id as number,
status: MesDvRepairStatusEnum.PREPARE,
};
await formApi.setFieldValue('id', id); await formApi.setFieldValue('id', id);
formType.value = 'update'; formType.value = 'update';
} else { } else {
@ -175,7 +185,9 @@ const [Modal, modalApi] = useVbenModal({
formType.value = data.formType; formType.value = data.formType;
formApi.setState({ schema: useFormSchema(data.formType, formApi) }); formApi.setState({ schema: useFormSchema(data.formType, formApi) });
formApi.setDisabled(isFormDisabled.value); formApi.setDisabled(isFormDisabled.value);
modalApi.setState({ showConfirmButton: ['create', 'update'].includes(formType.value) }); modalApi.setState({
showConfirmButton: ['create', 'update'].includes(formType.value),
});
if (!data?.id) { if (!data?.id) {
return; return;
} }
@ -193,7 +205,11 @@ const [Modal, modalApi] = useVbenModal({
<template> <template>
<Modal :title="getTitle" class="w-4/5"> <Modal :title="getTitle" class="w-4/5">
<Form class="mx-4" /> <Form class="mx-4" />
<LineList v-if="formData?.id" :disabled="isLineReadonly" :repair-id="formData.id" /> <LineList
v-if="formData?.id"
:disabled="isLineReadonly"
:repair-id="formData.id"
/>
<template #prepend-footer> <template #prepend-footer>
<div class="flex flex-auto items-center gap-2"> <div class="flex flex-auto items-center gap-2">
<Popconfirm <Popconfirm

View File

@ -143,7 +143,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
}); });
/** 打开维修明细表单 */ /** 打开维修明细表单 */
async function openForm(type: 'create' | 'update', row?: MesDvRepairLineApi.RepairLine) { async function openForm(
type: 'create' | 'update',
row?: MesDvRepairLineApi.RepairLine,
) {
formOpen.value = true; formOpen.value = true;
lineFormType.value = type; lineFormType.value = type;
await formApi.resetForm(); await formApi.resetForm();
@ -198,7 +201,11 @@ watch(
<div v-if="!disabled" class="mb-3"> <div v-if="!disabled" class="mb-3">
<TableAction <TableAction
:actions="[ :actions="[
{ label: '添加维修项目', type: 'primary', onClick: openForm.bind(null, 'create') }, {
label: '添加维修项目',
type: 'primary',
onClick: openForm.bind(null, 'create'),
},
]" ]"
/> />
</div> </div>
@ -206,7 +213,11 @@ watch(
<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',

View File

@ -44,7 +44,7 @@ const filteredList = computed(() => {
); );
// //
if ( if (
props.modelValue != null && props.modelValue !== null &&
!result.some((item) => item.id === props.modelValue) !result.some((item) => item.id === props.modelValue)
) { ) {
const current = list.value.find((item) => item.id === props.modelValue); const current = list.value.find((item) => item.id === props.modelValue);
@ -64,7 +64,10 @@ async function getList() {
function handleChange(value: SelectValue) { function handleChange(value: SelectValue) {
const subjectId = typeof value === 'number' ? value : undefined; const subjectId = typeof value === 'number' ? value : undefined;
emit('update:modelValue', subjectId); emit('update:modelValue', subjectId);
emit('change', list.value.find((item) => item.id === subjectId)); emit(
'change',
list.value.find((item) => item.id === subjectId),
);
} }
onMounted(getList); onMounted(getList);

View File

@ -51,7 +51,9 @@ export function useFormSchema(
{ {
type: 'default', type: 'default',
onClick: async () => { onClick: async () => {
const code = await generateAutoCode(MesAutoCodeRuleCode.DV_SUBJECT_CODE); const code = await generateAutoCode(
MesAutoCodeRuleCode.DV_SUBJECT_CODE,
);
await formApi?.setFieldValue('code', code); await formApi?.setFieldValue('code', code);
}, },
}, },

View File

@ -8,7 +8,11 @@ import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message } from 'ant-design-vue'; import { Button, message } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteSubject, exportSubject, getSubjectPage } from '#/api/mes/dv/subject'; import {
deleteSubject,
exportSubject,
getSubjectPage,
} from '#/api/mes/dv/subject';
import { $t } from '#/locales'; import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema } from './data'; import { useGridColumns, useGridFormSchema } from './data';

View File

@ -3,7 +3,11 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesMdAutoCodePartApi } from '#/api/mes/md/autocode/part'; import type { MesMdAutoCodePartApi } from '#/api/mes/md/autocode/part';
import type { MesMdAutoCodeRuleApi } from '#/api/mes/md/autocode/rule'; import type { MesMdAutoCodeRuleApi } from '#/api/mes/md/autocode/rule';
import { CommonStatusEnum, DICT_TYPE, MesAutoCodePartTypeEnum } from '@vben/constants'; import {
CommonStatusEnum,
DICT_TYPE,
MesAutoCodePartTypeEnum,
} from '@vben/constants';
import { getDictOptions } from '@vben/hooks'; import { getDictOptions } from '@vben/hooks';
import { z } from '#/adapter/form'; import { z } from '#/adapter/form';

View File

@ -41,8 +41,8 @@ function getMultipleSelectedRows() {
] as MesMdClientApi.Client[]; ] as MesMdClientApi.Client[];
records.forEach((row) => { records.forEach((row) => {
const rowId = row.id; const rowId = row.id;
if (rowId != null) { if (!rowId) {
selectedMap.set(rowId, row); selectedMap.set(rowId as number, row);
} }
}); });
return [...selectedMap.values()]; return [...selectedMap.values()];
@ -83,7 +83,7 @@ async function applyPreSelection() {
} }
const rows = getTableRows(); const rows = getTableRows();
for (const row of rows) { for (const row of rows) {
if (row.id == null || !preSelectedIds.value.includes(row.id)) { if (row.id === null || !preSelectedIds.value.includes(row.id as number)) {
continue; continue;
} }
if (multiple.value) { if (multiple.value) {

View File

@ -42,12 +42,12 @@ const showClear = computed(
props.allowClear && props.allowClear &&
!props.disabled && !props.disabled &&
hovering.value && hovering.value &&
props.modelValue != null, props.modelValue !== null,
); );
/** 根据客户编号回显选择器 */ /** 根据客户编号回显选择器 */
async function resolveItemById(id: number | undefined) { async function resolveItemById(id: number | undefined) {
if (id == null) { if (!id) {
selectedItem.value = undefined; selectedItem.value = undefined;
return; return;
} }
@ -83,7 +83,9 @@ function handleClick(event: MouseEvent) {
clearSelected(); clearSelected();
return; return;
} }
const selectedIds = props.modelValue == null ? [] : [props.modelValue]; const selectedIds = (
props.modelValue === null ? [] : [props.modelValue]
) as number[];
dialogRef.value?.open(selectedIds, { multiple: false }); dialogRef.value?.open(selectedIds, { multiple: false });
} }

View File

@ -4,7 +4,11 @@ import type { MesMdClientApi } from '#/api/mes/md/client';
import { h } from 'vue'; import { h } from 'vue';
import { CommonStatusEnum, DICT_TYPE, MesAutoCodeRuleCode } from '@vben/constants'; import {
CommonStatusEnum,
DICT_TYPE,
MesAutoCodeRuleCode,
} 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';

View File

@ -68,7 +68,7 @@ async function openModal(itemId: number, selectedBomItemId?: number) {
list.value = await getProductBomListByItemId(itemId); list.value = await getProductBomListByItemId(itemId);
gridApi.setGridOptions({ data: list.value }); gridApi.setGridOptions({ data: list.value });
await nextTick(); await nextTick();
if (selectedBomItemId != null) { if (selectedBomItemId !== null) {
const match = list.value.find( const match = list.value.find(
(row) => row.bomItemId === selectedBomItemId, (row) => row.bomItemId === selectedBomItemId,
); );

View File

@ -44,19 +44,19 @@ const showClear = computed(
props.allowClear && props.allowClear &&
!props.disabled && !props.disabled &&
hovering.value && hovering.value &&
props.modelValue != null, props.modelValue !== null,
); );
/** 根据 BOM 子物料编号回显选择器 */ /** 根据 BOM 子物料编号回显选择器 */
async function resolveBomById(bomItemId: number | undefined) { async function resolveBomById(bomItemId: number | undefined) {
if (bomItemId == null || props.itemId == null) { if (bomItemId === null || props.itemId === null) {
selectedBom.value = undefined; selectedBom.value = undefined;
return; return;
} }
if (selectedBom.value?.bomItemId === bomItemId) { if (selectedBom.value?.bomItemId === bomItemId) {
return; return;
} }
const list = await getProductBomListByItemId(props.itemId); const list = await getProductBomListByItemId(props.itemId as number);
selectedBom.value = list.find((item) => item.bomItemId === bomItemId); selectedBom.value = list.find((item) => item.bomItemId === bomItemId);
} }
@ -86,7 +86,7 @@ function clearSelected() {
/** 打开 BOM 物料选择弹窗 */ /** 打开 BOM 物料选择弹窗 */
function handleClick(event: MouseEvent) { function handleClick(event: MouseEvent) {
if (props.disabled || props.itemId == null) { if (props.disabled || props.itemId === null) {
return; return;
} }
const target = event.target as HTMLElement; const target = event.target as HTMLElement;
@ -95,7 +95,7 @@ function handleClick(event: MouseEvent) {
clearSelected(); clearSelected();
return; return;
} }
dialogRef.value?.open(props.itemId, props.modelValue); dialogRef.value?.open(props.itemId as number, props.modelValue);
} }
/** 回填选中的 BOM 物料 */ /** 回填选中的 BOM 物料 */

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