feat: form组件替换

This commit is contained in:
rd
2025-09-03 16:28:19 +08:00
parent 64a5b41a4e
commit a29580ff1e
42 changed files with 394 additions and 453 deletions

View File

@ -46,27 +46,27 @@
<template #title>
<span class="modal-title">{{ form.id > 0 ? '编辑品牌' : '添加品牌' }}</span>
</template>
<a-form :model="form" :rules="formRule" ref="formRef" layout="horizontal" auto-label-width>
<a-form-item field="name" label="品牌名称">
<Form :model="form" :rules="formRule" ref="formRef" layout="horizontal" auto-label-width labelAlign="right" :labelCol="{ span: 4 }" :wrapperCol="{ span: 20 }">
<FormItem name="name" label="品牌名称">
<a-input v-model="form.name" class="h-36px" placeholder="请输入..." />
</a-form-item>
<a-form-item field="logo" class="form-item-logo" label="标准版Logo">
<a-space>
</FormItem>
<FormItem name="logo" class="form-item-logo" label="标准版Logo">
<div class="inline-flex">
<ImageUpload v-model="form.logo" :limit="1"></ImageUpload>
</a-space>
<a-space>
</div>
<div class="inline-flex">
<span class="form-tip">品牌常规展示使用支持PNGJPG格式</span>
</a-space>
</a-form-item>
<a-form-item field="otherLogos" class="form-item-logo" label="其他Logo">
</div>
</FormItem>
<FormItem name="otherLogos" class="form-item-logo" label="其他Logo">
<ImageUpload v-model="form.other_logos" :limit="3"></ImageUpload>
</a-form-item>
<a-form-item field="slogan" label="Slogan">
</FormItem>
<FormItem name="slogan" label="Slogan">
<a-textarea v-model="form.slogan" placeholder="请输入..." :max-length="50" show-word-limit />
</a-form-item>
</a-form>
</FormItem>
</Form>
<template #footer>
<Button @click="handleModalCancel" class="mr-8px">取消</Button>
<Button @click="handleModalCancel">取消</Button>
<Button type="primary" @click="handleModalOk">{{ btn_str }}</Button>
</template>
</Modal>
@ -128,7 +128,7 @@
import { ref, computed, reactive, onMounted } from 'vue';
import { Message } from '@arco-design/web-vue';
import { IconDelete } from '@arco-design/web-vue/es/icon';
import { Button, Modal } from 'ant-design-vue';
import { Button, Modal, Form, FormItem } from 'ant-design-vue';
import {
addMaterials,
@ -233,20 +233,18 @@ function handleModalOk() {
formRef.value
.validate()
.then((valid) => {
if (!valid) {
if (form.id) {
updateMaterials(form.id, form).then(() => {
Message.success('修改成功');
handleSearch();
});
} else {
addMaterials(form).then((response) => {
Message.success('新增成功');
handleSearch();
});
}
modalVisible.value = false;
if (form.id) {
updateMaterials(form.id, form).then(() => {
Message.success('修改成功');
handleSearch();
});
} else {
addMaterials(form).then((response) => {
Message.success('新增成功');
handleSearch();
});
}
modalVisible.value = false;
})
.catch((error) => {
console.error('验证失败:', error);

View File

@ -10,7 +10,7 @@
centered
wrapClassName="authorized-account-modal"
:maskClosable="false"
:footer="modalState !== MODAL_STATE.LOADING"
:footer="modalState === MODAL_STATE.LOADING ? null : footer"
@cancel="close"
>
<div class="flex flex-col items-center">

View File

@ -14,8 +14,8 @@
<div class="mb-16px t1">
{{ `已选${accountTagList.length}个账号` }}
</div>
<a-form ref="formRef" :model="form" layout="horizontal" auto-label-width>
<a-form-item label="编辑方式" required>
<Form ref="formRef" :model="form" layout="horizontal" auto-label-width>
<FormItem label="编辑方式" required>
<a-radio-group v-model="editType">
<a-radio value="all">
<div class="flex items-center">
@ -27,8 +27,8 @@
</a-radio>
<a-radio value="each">分别编辑</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="选择标签" required>
</FormItem>
<FormItem label="选择标签" required>
<template v-if="editType === 'all'">
<div class="flex items-center w-100%">
<a-select
@ -44,7 +44,7 @@
<span class="ml-12px">{{ `${form.tags.length}/5` }}</span>
</div>
</template>
</a-form-item>
</FormItem>
<!-- 分别编辑 -->
<template v-if="editType === 'each'">
@ -75,7 +75,7 @@
</template>
</a-table>
</template>
</a-form>
</Form>
<template #footer>
<Button size="large" @click="onClose">取消</Button>
<Button type="primary" size="large" @click="onSubmit">确定</Button>
@ -85,7 +85,7 @@
<script setup>
import { ref, reactive } from 'vue';
import { Button, Modal } from 'ant-design-vue';
import { Button, Modal, Form, FormItem } from 'ant-design-vue';
import { fetchAccountTags, batchPutTag } from '@/api/all/propertyMarketing';
import icon1 from '@/assets/img/icon-question.png';

View File

@ -11,11 +11,11 @@
centered
@cancel="onClose"
>
<a-form ref="formRef" :model="form" :rules="rules" layout="horizontal" auto-label-width>
<a-form-item :label="isEdit ? '分组名称' : '新分组名称'" field="name" required>
<Form ref="formRef" :model="form" :rules="rules" layout="horizontal" auto-label-width>
<FormItem :label="isEdit ? '分组名称' : '新分组名称'" name="name" required>
<a-input v-model="form.name" placeholder="请输入…" />
</a-form-item>
</a-form>
</FormItem>
</Form>
<template #footer>
<Button @click="onClose">取消</Button>
<Button type="primary" class="ml-16px" @click="onSubmit">确认</Button>
@ -25,7 +25,7 @@
<script setup>
import { ref, watch, nextTick } from 'vue';
import { Button, Modal } from 'ant-design-vue';
import { Button, Modal, Form, FormItem } from 'ant-design-vue';
import { postAccountGroups, putGroup } from '@/api/all/propertyMarketing';
const emits = defineEmits(['success', 'close']);
@ -63,16 +63,14 @@ const open = (record = {}) => {
};
async function onSubmit() {
formRef.value.validate(async (errors) => {
if (!errors) {
const _fn = isEdit.value ? putGroup : postAccountGroups;
const _params = isEdit.value ? { id: groupId.value, ...form.value } : form.value;
const { code } = await _fn(_params);
if (code === 200) {
AMessage.success(isEdit.value ? '编辑成功' : '添加成功');
emits('success');
onClose();
}
formRef.value.validate().then(async () => {
const _fn = isEdit.value ? putGroup : postAccountGroups;
const _params = isEdit.value ? { id: groupId.value, ...form.value } : form.value;
const { code } = await _fn(_params);
if (code === 200) {
AMessage.success(isEdit.value ? '编辑成功' : '添加成功');
emits('success');
onClose();
}
});
}

View File

@ -7,7 +7,7 @@
v-model:open="visible"
width="900px"
wrapClassName="account-manage-modal"
:footer="false"
:footer="null"
centered
title="分组管理"
:maskClosable="false"

View File

@ -10,7 +10,7 @@
title="重新授权"
wrapClassName="reauthorize-account-modal"
:maskClosable="false"
:footer="modalState !== MODAL_STATE.LOADING"
:footer="modalState === MODAL_STATE.LOADING ? null : footer"
@cancel="close"
>
<div class="flex flex-col items-center">

View File

@ -7,11 +7,11 @@
centered
@cancel="onClose"
>
<a-form ref="formRef" :model="form" :rules="rules" layout="horizontal" auto-label-width>
<a-form-item :label="isEdit ? '标签名称' : '新标签名称'" field="name" required>
<Form ref="formRef" :model="form" :rules="rules" layout="horizontal" auto-label-width>
<FormItem :label="isEdit ? '标签名称' : '新标签名称'" name="name" required>
<a-input v-model="form.name" placeholder="请输入…" />
</a-form-item>
</a-form>
</FormItem>
</Form>
<template #footer>
<Button @click="onClose">取消</Button>
<Button type="primary" class="ml-16px" @click="onSubmit">确认</Button>
@ -21,7 +21,7 @@
<script setup>
import { ref, nextTick } from 'vue';
import { Button, Modal } from 'ant-design-vue';
import { Button, Modal, Form, FormItem } from 'ant-design-vue';
import { postAccountTags, putTag } from '@/api/all/propertyMarketing';
const emits = defineEmits(['success', 'close']);
@ -59,8 +59,8 @@ const open = (record = {}) => {
};
async function onSubmit() {
formRef.value.validate(async (errors) => {
if (!errors) {
formRef.value.validate()
.then(async () => {
const _fn = isEdit.value ? putTag : postAccountTags;
const _params = isEdit.value ? { id: tagId.value, ...form.value } : form.value;
const { code } = await _fn(_params);
@ -69,8 +69,7 @@ async function onSubmit() {
emits('success');
onClose();
}
}
});
})
}
defineExpose({ open });

View File

@ -7,7 +7,7 @@
v-model:open="visible"
width="800px"
wrapClassName="tags-manage-modal"
:footer="false"
:footer="null"
centered
title="标签管理"
:maskClosable="false"

View File

@ -3,14 +3,14 @@
.tags-manage-modal {
border-radius: 8px;
.arco-modal-body {
.ant-modal-body {
// padding: 24px 24px 44px !important;
overflow: hidden;
display: flex;
flex-direction: column;
.arco-btn {
.arcanto-btn {
width: fit-content;
.arco-btn-icon {
.ant-btn-icon {
line-height: 16px;
}
}

View File

@ -144,12 +144,10 @@ const handleEdit = () => {
const setCurrent = async (current) => {
if (isFirstStep.value) {
const valid = await compRef.value.validate();
if (!valid) {
return;
}
compRef.value.validate().then(() => {
currentStep.value = current;
});
}
currentStep.value = current;
};
const onPrev = () => {
currentStep.value--;

View File

@ -1,12 +1,12 @@
<template>
<a-form ref="formRef" :model="formQuery" :rules="rules" layout="horizontal" auto-label-width class="h-448px">
<a-form-item label="项目名称" required field="name">
<Form ref="formRef" :model="formQuery" :rules="rules" layout="horizontal" auto-label-width class="h-448px">
<FormItem label="项目名称" required name="name">
<a-input v-model="formQuery.name" placeholder="请输入项目名称" size="large" class="!w-400px" />
</a-form-item>
<a-form-item label="项目预算" field="budget">
</FormItem>
<FormItem label="项目预算" name="budget">
<a-input v-model="formQuery.budget" placeholder="请输入项目预算" size="large" class="!w-400px" />
</a-form-item>
<a-form-item label="项目目标" field="target">
</FormItem>
<FormItem label="项目目标" name="target">
<a-textarea
v-model="formQuery.target"
placeholder="请输入项目目标"
@ -14,8 +14,8 @@
show-word-limit
class="h-154px"
/>
</a-form-item>
<a-form-item label="项目背景" field="background">
</FormItem>
<FormItem label="项目背景" name="background">
<a-textarea
v-model="formQuery.background"
placeholder="请输入项目背景"
@ -23,11 +23,13 @@
show-word-limit
class="h-154px"
/>
</a-form-item>
</a-form>
</FormItem>
</Form>
</template>
<script setup>
import { Form, FormItem } from 'ant-design-vue';
const props = defineProps({
formQuery: {
type: Object,
@ -42,8 +44,7 @@ const rules = {
};
const validate = async () => {
const errors = await formRef.value.validate();
return !errors
return formRef.value.validate()
};
const reset = () => {

View File

@ -11,11 +11,11 @@
centered
@cancel="onClose"
>
<a-form ref="formRef" :model="form" :rules="rules" layout="horizontal" auto-label-width>
<a-form-item :label="isEdit ? '分组名称' : '新分组名称'" field="name" required>
<Form ref="formRef" :model="form" :rules="rules" layout="horizontal" auto-label-width>
<FormItem :label="isEdit ? '分组名称' : '新分组名称'" name="name" required>
<a-input v-model="form.name" placeholder="请输入…" />
</a-form-item>
</a-form>
</FormItem>
</Form>
<template #footer>
<Button @click="onClose">取消</Button>
<Button type="primary" class="ml-16px" @click="onSubmit">确认</Button>
@ -25,7 +25,7 @@
<script setup>
import { ref, watch, nextTick } from 'vue';
import { Button, Modal } from 'ant-design-vue';
import { Button, Modal, Form, FormItem } from 'ant-design-vue';
import { postPlacementAccountProjectGroups, putPlacementAccountProjectGroups } from '@/api/all/propertyMarketing';
const emits = defineEmits(['success', 'close']);
@ -63,16 +63,14 @@ const open = (record = {}) => {
};
async function onSubmit() {
formRef.value.validate(async (errors) => {
if (!errors) {
const _fn = isEdit.value ? putPlacementAccountProjectGroups : postPlacementAccountProjectGroups;
const _params = isEdit.value ? { id: groupId.value, ...form.value } : form.value;
const { code } = await _fn(_params);
if (code === 200) {
AMessage.success(isEdit.value ? '编辑成功' : '添加成功');
emits('success');
onClose();
}
formRef.value.validate().then(async () => {
const _fn = isEdit.value ? putPlacementAccountProjectGroups : postPlacementAccountProjectGroups;
const _params = isEdit.value ? { id: groupId.value, ...form.value } : form.value;
const { code } = await _fn(_params);
if (code === 200) {
AMessage.success(isEdit.value ? '编辑成功' : '添加成功');
emits('success');
onClose();
}
});
}

View File

@ -7,7 +7,7 @@
v-model:open="visible"
width="900px"
wrapClassName="put-account-group-manage-modal"
:footer="false"
:footer="null"
title="分组管理"
centered
:maskClosable="false"

View File

@ -13,17 +13,25 @@
centered
@cancel="onClose"
>
<a-form ref="formRef" :model="form" :rules="rules" layout="horizontal" auto-label-width>
<a-form-item v-if="!isEdit" label="上传方式" required>
<Form
ref="formRef"
:model="form"
:rules="formRules"
layout="horizontal"
labelAlign="right"
:labelCol="{ span: 5 }"
:wrapperCol="{ span: 19 }"
>
<FormItem v-if="!isEdit" label="上传方式" required>
<a-radio-group v-model="uploadType">
<a-radio value="manual">手动添加账户</a-radio>
<a-radio value="batch">批量导入账户</a-radio>
</a-radio-group>
</a-form-item>
</FormItem>
<!-- 批量导入账户模式下的内容 -->
<template v-if="isBatchImport">
<a-form-item label="账户文件" required>
<FormItem label="账户文件" required>
<!-- 默认状态 -->
<div class="upload-block">
<template v-if="uploadStatus === UploadStatus.DEFAULT">
@ -72,33 +80,33 @@
<span class="dt">下载账户导入模板.xlsx</span>
</div>
</div>
</a-form-item>
</FormItem>
</template>
<!-- 手动添加账户 -->
<template v-else>
<template v-if="isEdit">
<a-form-item label="账户名称" field="name">
<a-input v-model="form.name" placeholder="请输入..." size="large" disabled />
</a-form-item>
<a-form-item label="账户ID" field="account_id">
<a-input v-model="form.account_id" placeholder="请输入..." size="large" disabled />
</a-form-item>
<a-form-item label="状态" field="status">
<FormItem label="账户名称" name="name">
<Input v-model:value="form.name" placeholder="请输入..." disabled />
</FormItem>
<FormItem label="账户ID" name="account_id">
<Input v-model:value="form.account_id" placeholder="请输入..." size="large" disabled />
</FormItem>
<FormItem label="状态" name="status">
<StatusBox :status="form.status" />
</a-form-item>
</FormItem>
</template>
<a-form-item label="手机号" field="mobile" required>
<a-input v-model="form.mobile" placeholder="请输入..." size="large" />
</a-form-item>
<a-form-item label="运营人员" field="operator_name" required>
<a-input v-model="form.operator_name" placeholder="请输入..." class="w-240px" size="large" />
</a-form-item>
<a-form-item label="号码持有人" field="holder_name" required>
<a-input v-model="form.holder_name" placeholder="请输入..." class="w-240px" size="large" />
</a-form-item>
<a-form-item label="运营平台" :required="!isEdit">
<FormItem label="手机号" name="mobile">
<Input v-model:value="form.mobile" placeholder="请输入..." size="large" />
</FormItem>
<FormItem label="运营人员" name="operator_name">
<Input v-model:value="form.operator_name" placeholder="请输入..." class="w-240px" size="large" />
</FormItem>
<FormItem label="号码持有人" name="holder_name">
<Input v-model:value="form.holder_name" placeholder="请输入..." class="w-240px" size="large" />
</FormItem>
<FormItem label="运营平台" :required="!isEdit">
<div v-if="isEdit" class="flex items-center">
<img :src="PLATFORM_LIST[form.platform].icon" width="14" height="14" class="mr-4px" />
<span>{{ PLATFORM_LIST[form.platform].label }}</span>
@ -111,19 +119,19 @@
</div>
</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="所属项目" field="project_ids">
</FormItem>
<FormItem label="所属项目" name="project_ids">
<CommonSelect v-model="form.project_ids" :options="projects" placeholder="请选择…" size="large" />
</a-form-item>
</FormItem>
<template v-if="isEdit">
<a-form-item label="账户总消耗" field="total_use_amount">
<a-input v-model="form.total_use_amount" placeholder="请输入..." size="large" disabled />
</a-form-item>
<a-form-item label="账户余额" field="balance_amount">
<a-input v-model="form.balance_amount" placeholder="请输入..." size="large" disabled />
</a-form-item>
<FormItem label="账户总消耗" name="total_use_amount">
<Input v-model:value="form.total_use_amount" placeholder="请输入..." size="large" disabled />
</FormItem>
<FormItem label="账户余额" name="balance_amount">
<Input v-model:value="form.balance_amount" placeholder="请输入..." size="large" disabled />
</FormItem>
</template>
<a-form-item label="同步项目数据" field="is_sync_project">
<FormItem label="同步项目数据" name="is_sync_project">
<template #label>
<span class="label">同步项目数据</span>
<a-tooltip content="同步项目数据后,账户数据将同步到项目中">
@ -131,9 +139,9 @@
</a-tooltip>
</template>
<a-switch v-model="form.is_sync_project" size="medium" :checked-value="1" :unchecked-value="0" />
</a-form-item>
</FormItem>
</template>
</a-form>
</Form>
<template #footer>
<Button size="large" @click="onClose">取消</Button>
<Button type="primary" size="large" @click="onSubmit" :loading="importLoading">
@ -147,10 +155,8 @@
</template>
<script setup>
// 添加Modal导入
import { Modal } from 'ant-design-vue';
import { Modal, Form, FormItem, Button, Input } from 'ant-design-vue';
import { ref, defineEmits } from 'vue';
import { Button } from 'ant-design-vue';
import AuthorizedAccountModal from '../authorized-account-modal';
// import ImportPromptModal from '../import-prompt-modal';
@ -205,26 +211,26 @@ const form = ref(cloneDeep(INITIAL_FORM));
const projects = ref([]);
const importLoading = ref(false);
const rules = {
const formRules = {
mobile: [
{
required: true,
message: '请填写手机号',
trigger: ['blur', 'change'],
},
{
validator: (value, callback) => {
validator: (_rule, value) => {
if (!value) {
return Promise.reject('请填写手机号');
}
console.log({ value });
if (!/^1[3-9]\d{9}$/.test(value)) {
callback('手机号格式不正确');
return Promise.reject('手机号格式不正确');
} else {
callback();
return Promise.resolve();
}
},
trigger: ['blur', 'change'],
},
],
operator_name: [{ required: true, message: '请输入运营人员' }],
holder_name: [{ required: true, message: '请输入号码持有人' }],
operator_name: [{ required: true, message: '请输入运营人员', trigger: ['blur', 'change'] }],
holder_name: [{ required: true, message: '请输入号码持有人', trigger: ['blur', 'change'] }],
};
const isBatchImport = computed(() => uploadType.value === 'batch');
@ -353,10 +359,8 @@ async function onSubmit() {
return;
}
formRef.value.validate(async (errors) => {
if (!errors) {
isEdit.value ? handleEdit() : handleAdd();
}
formRef.value.validate().then(() => {
isEdit.value ? handleEdit() : handleAdd();
});
}

View File

@ -4,7 +4,7 @@
.w-240px {
width: 240px !important;
}
.arco-modal-body {
.ant-modal-body {
.upload-block {
width: 100%;
.dt {

View File

@ -9,7 +9,7 @@
title="获取凭证"
wrapClassName="authorized-account-modal"
:maskClosable="false"
:footer="!isLoading"
:footer="isLoading ? null : footer"
centered
@cancel="close"
>
@ -45,14 +45,14 @@
<p class="s2">{{ `数据初始化${isSuccess ? '成功' : '失败'}` }}</p>
<p v-if="!isSuccess" class="red-text">失败原因{{ failReason || '-' }}</p>
</template>
<a-form v-else ref="formRef" :model="form" :rules="rules" layout="horizontal" auto-label-width>
<a-form-item label="账户" field="account">
<Form v-else ref="formRef" :model="form" :rules="rules" layout="horizontal" auto-label-width>
<FormItem label="账户" name="account">
<a-input v-model="form.account" placeholder="请输入..." size="large" />
</a-form-item>
<a-form-item label="密码" field="password">
</FormItem>
<FormItem label="密码" name="password">
<a-input-password v-model="form.password" placeholder="请输入..." size="large" />
</a-form-item>
</a-form>
</FormItem>
</Form>
</template>
</div>
<template #footer>
@ -66,7 +66,7 @@
<script setup>
// 添加Modal导入
import { Modal } from 'ant-design-vue';
import { Modal, Form, FormItem } from 'ant-design-vue';
import dayjs from 'dayjs';
import { Button } from 'ant-design-vue';
import { defineExpose, ref, computed, defineEmits } from 'vue';
@ -283,8 +283,7 @@ const handleOk = () => {
}
// 未完成,校验表单
formRef.value.validate(async (errors) => {
if (errors) return;
formRef.value.validate().then(() => {
if (shouldSelectSubAccount.value) {
visible.value = false;
selectSubAccountModalRef.value.open({