mirror of
https://github.com/1Panel-dev/CordysCRM.git
synced 2026-05-24 03:38:42 +08:00
feat: opportunityAddRuleApi
This commit is contained in:
@@ -5,4 +5,12 @@ export enum CompanyTypeEnum {
|
||||
INTERNAL = 'INTERNAL', // 国际飞书
|
||||
}
|
||||
|
||||
export default {};
|
||||
// 操作符号
|
||||
export enum OperatorEnum {
|
||||
EQ = 'EQ', // 等于
|
||||
NE = 'NE', // 不等于
|
||||
GT = 'GT', // 大于
|
||||
GE = 'GE', // 大于等于
|
||||
LT = 'LT', // 小于
|
||||
LE = 'LE', // 小于等于
|
||||
}
|
||||
|
||||
@@ -23,3 +23,50 @@ export interface ModuleSortParams {
|
||||
end: number;
|
||||
dragModuleId: string; // 拖拽模块ID
|
||||
}
|
||||
|
||||
export interface ModuleUserScopedItem {
|
||||
id: string;
|
||||
scope: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ModuleConditionsItem {
|
||||
column: string;
|
||||
operator: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface OpportunityBaseInfoItem {
|
||||
name: string;
|
||||
enable: boolean;
|
||||
expireNotice: boolean; // 到期提醒
|
||||
noticeDays: number; // 提前提醒天数
|
||||
operator: string; // 操作符
|
||||
auto: boolean; // 自动回收
|
||||
}
|
||||
|
||||
// 模块商机列表
|
||||
export interface OpportunityItem extends OpportunityBaseInfoItem {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
ownerId: string; // 管理员ID
|
||||
scopeId: string; // 范围ID
|
||||
condition: string; // 回收条件
|
||||
createUser: string;
|
||||
updateUser: string;
|
||||
createTime: number;
|
||||
updateTime: number;
|
||||
members: ModuleUserScopedItem[]; // 成员集合
|
||||
owners: ModuleUserScopedItem[]; // 管理员集合
|
||||
}
|
||||
|
||||
// 模块商机详情
|
||||
export interface OpportunityDetail extends OpportunityBaseInfoItem {
|
||||
id?: string;
|
||||
conditions: ModuleConditionsItem[]; // 规则条件集合
|
||||
}
|
||||
|
||||
export interface OpportunityParams extends OpportunityDetail {
|
||||
scopeIds: string[];
|
||||
ownerIds: string[];
|
||||
}
|
||||
|
||||
@@ -10,7 +10,13 @@ import {
|
||||
toggleModuleNavStatusUrl,
|
||||
updateOpportunityRuleUrl,
|
||||
} from '@lib/shared/api/requrls/system/module';
|
||||
import type { ModuleNavBaseInfoItem, ModuleSortParams } from '@lib/shared/models/system/module';
|
||||
import type { CommonList, TableQueryParams } from '@lib/shared/models/common';
|
||||
import type {
|
||||
ModuleNavBaseInfoItem,
|
||||
ModuleSortParams,
|
||||
OpportunityDetail,
|
||||
OpportunityItem,
|
||||
} from '@lib/shared/models/system/module';
|
||||
|
||||
// 模块首页-导航模块列表
|
||||
export function getModuleNavConfigList(data: { organizationId: string }) {
|
||||
@@ -27,18 +33,18 @@ export function toggleModuleNavStatus(id: string) {
|
||||
return CDR.get({ url: `${toggleModuleNavStatusUrl}/${id}` });
|
||||
}
|
||||
|
||||
// 模块-商机-商机规则列表 TODO 类型
|
||||
export function getOpportunityList(data: any) {
|
||||
return CDR.post({ url: getOpportunityListUrl, data });
|
||||
// 模块-商机-商机规则列表
|
||||
export function getOpportunityList(data: TableQueryParams) {
|
||||
return CDR.post<CommonList<OpportunityItem>>({ url: getOpportunityListUrl, data });
|
||||
}
|
||||
|
||||
// 模块-商机-添加商机规则 TODO 类型
|
||||
export function addOpportunityRule(data: any) {
|
||||
// 模块-商机-添加商机规则
|
||||
export function addOpportunityRule(data: OpportunityDetail) {
|
||||
return CDR.post({ url: addOpportunityRuleUrl, data });
|
||||
}
|
||||
|
||||
// 模块-商机-更新商机规则 TODO 类型
|
||||
export function updateOpportunityRule(data: any) {
|
||||
// 模块-商机-更新商机规则
|
||||
export function updateOpportunityRule(data: OpportunityDetail) {
|
||||
return CDR.post({ url: updateOpportunityRuleUrl, data });
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
class="z-[1] w-[34px]"
|
||||
@click="changeAllOr"
|
||||
>
|
||||
{{ form.allOr === 'all' ? 'all' : 'or' }}
|
||||
{{ form.allOr === 'AND' ? 'all' : 'or' }}
|
||||
</CrmTag>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
@@ -171,7 +171,7 @@
|
||||
});
|
||||
|
||||
function changeAllOr() {
|
||||
form.value.allOr = form.value.allOr === 'all' ? 'or' : 'all';
|
||||
form.value.allOr = form.value.allOr === 'ALL' ? 'OR' : 'AND';
|
||||
}
|
||||
|
||||
function fieldNotRepeat(value: any[] | string | undefined, index: number, field: string, msg?: string) {
|
||||
|
||||
@@ -10,7 +10,12 @@
|
||||
/>
|
||||
<div v-else class="flex items-center gap-[8px]">
|
||||
<slot>{{ value }} </slot>
|
||||
<CrmIcon class="cursor-pointer text-[var(--text-n4)]" type="iconicon_edit" :size="16" @click="enableEditMode" />
|
||||
<CrmIcon
|
||||
class="table-row-edit cursor-pointer text-[var(--text-n4)]"
|
||||
type="iconicon_edit"
|
||||
:size="16"
|
||||
@click="enableEditMode"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -55,3 +60,16 @@
|
||||
isEditing.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.n-data-table {
|
||||
.table-row-edit {
|
||||
@apply invisible;
|
||||
}
|
||||
.n-data-table-tr:not(.n-data-table-tr--summary):hover {
|
||||
.table-row-edit {
|
||||
@apply visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
12
frontend/packages/web/src/config/operator.ts
Normal file
12
frontend/packages/web/src/config/operator.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
import { OperatorEnum } from '@lib/shared/enums/commonEnum';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
export const EQUAL = { value: OperatorEnum.EQ, label: t('common.equal') }; // 等于
|
||||
export const NOT_EQUAL = { value: OperatorEnum.NE, label: t('common.notEqual') }; // 不等于
|
||||
export const GT = { value: OperatorEnum.GT, label: t('common.gt') }; // 大于
|
||||
export const GE = { value: OperatorEnum.GE, label: t('common.ge') }; // 大于等于
|
||||
export const LT = { value: OperatorEnum.LT, label: t('common.lt') }; // 小于
|
||||
export const LE = { value: OperatorEnum.LE, label: t('common.le') }; // 小于等于
|
||||
@@ -238,4 +238,10 @@ export default {
|
||||
'common.confirmEnableTitle': 'Are you sure to enable {name}?',
|
||||
'common.connectionSuccess': 'Connection success',
|
||||
'common.closed': 'Closed',
|
||||
'common.equal': 'Equal',
|
||||
'common.notEqual': 'Not equal',
|
||||
'common.gt': 'Greater than',
|
||||
'common.ge': 'Greater than or equal to',
|
||||
'common.lt': 'Less than',
|
||||
'common.le': 'Less than or equal to',
|
||||
};
|
||||
|
||||
@@ -238,4 +238,10 @@ export default {
|
||||
'common.confirmEnableTitle': '确认启用 {name} 吗?',
|
||||
'common.connectionSuccess': '连接成功',
|
||||
'common.closed': '已关闭',
|
||||
'common.equal': '等于',
|
||||
'common.notEqual': '不等于',
|
||||
'common.gt': '大于',
|
||||
'common.ge': '大于等于',
|
||||
'common.lt': '小于',
|
||||
'common.le': '小于等于',
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
v-model:show="visible"
|
||||
:width="800"
|
||||
:title="t('module.businessManage.businessCloseRule')"
|
||||
:show-continue="true"
|
||||
:show-continue="!form.id"
|
||||
:loading="loading"
|
||||
@confirm="confirmHandler(false)"
|
||||
@continue="confirmHandler(true)"
|
||||
@@ -22,10 +22,10 @@
|
||||
<n-form-item
|
||||
require-mark-placement="left"
|
||||
label-placement="left"
|
||||
path="ruleName"
|
||||
path="name"
|
||||
:label="t('opportunity.ruleName')"
|
||||
>
|
||||
<n-input v-model:value="form.ruleName" type="text" :placeholder="t('common.pleaseInput')" />
|
||||
<n-input v-model:value="form.name" type="text" :placeholder="t('common.pleaseInput')" />
|
||||
</n-form-item>
|
||||
</div>
|
||||
<div class="flex">
|
||||
@@ -33,10 +33,10 @@
|
||||
<n-form-item
|
||||
require-mark-placement="left"
|
||||
label-placement="left"
|
||||
path="adminId"
|
||||
path="ownerIds"
|
||||
:label="t('opportunity.admin')"
|
||||
>
|
||||
<n-select v-model:value="form.adminId" :placeholder="t('common.pleaseSelect')" :options="adminOptions" />
|
||||
<CrmUserTagSelector v-model:selected-list="form.ownerIds" />
|
||||
</n-form-item>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
@@ -46,25 +46,22 @@
|
||||
path="userId"
|
||||
:label="t('opportunity.members')"
|
||||
>
|
||||
<CrmUserSelect
|
||||
v-model:value="form.userId"
|
||||
value-field="id"
|
||||
label-field="name"
|
||||
mode="remote"
|
||||
filterable
|
||||
:fetch-api="getUserOptions"
|
||||
/>
|
||||
<CrmUserTagSelector v-model:selected-list="form.scopeIds" />
|
||||
</n-form-item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="crm-module-form-title"> {{ t('module.businessManage.businessCloseRule') }}</div>
|
||||
<!-- 自动关闭 -->
|
||||
<n-form-item
|
||||
v-if="!form.id"
|
||||
require-mark-placement="left"
|
||||
label-placement="left"
|
||||
path="autoClose"
|
||||
path="auto"
|
||||
:label="t('opportunity.autoClose')"
|
||||
:show-feedback="false"
|
||||
>
|
||||
<n-radio-group v-model:value="form.autoClose" name="radiogroup">
|
||||
<n-radio-group v-model:value="form.auto" name="radiogroup">
|
||||
<n-space>
|
||||
<n-radio key="yes" :value="true">
|
||||
{{ t('common.yes') }}
|
||||
@@ -76,21 +73,23 @@
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<CrmBatchForm
|
||||
v-if="form.autoRecycle"
|
||||
v-if="form.auto"
|
||||
ref="batchFormRef"
|
||||
class="mt-[16px]"
|
||||
:models="formItemModel"
|
||||
:default-list="form.list"
|
||||
:default-list="form.conditions"
|
||||
:add-text="t('module.clue.addConditions')"
|
||||
:validate-when-add="true"
|
||||
show-all-or
|
||||
/>
|
||||
<n-form-item
|
||||
require-mark-placement="left"
|
||||
label-placement="left"
|
||||
class="mt-[16px]"
|
||||
path="expirationReminder"
|
||||
path="expireNotice"
|
||||
:label="t('opportunity.expirationReminder')"
|
||||
>
|
||||
<n-radio-group v-model:value="form.expirationReminder" name="radiogroup">
|
||||
<n-radio-group v-model:value="form.expireNotice" name="radiogroup">
|
||||
<n-space>
|
||||
<n-radio key="yes" :value="true">
|
||||
{{ t('common.yes') }}
|
||||
@@ -102,54 +101,19 @@
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
v-if="form.expireNotice"
|
||||
require-mark-placement="left"
|
||||
label-placement="left"
|
||||
path="reminderAdvance"
|
||||
path="noticeDays"
|
||||
:label="t('module.reminderAdvance')"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="form.reminderAdvance"
|
||||
<n-input-number
|
||||
v-model:value="form.noticeDays"
|
||||
class="crm-reminder-advance-input"
|
||||
type="text"
|
||||
:placeholder="t('common.pleaseInput')"
|
||||
/>
|
||||
<div class="flex flex-nowrap"> {{ t('module.reminderDays') }}</div>
|
||||
</n-form-item>
|
||||
<div class="crm-module-form-title"> {{ t('opportunity.clueRecoveryRule') }}</div>
|
||||
<n-form-item
|
||||
require-mark-placement="left"
|
||||
label-placement="left"
|
||||
path="expirationReminder"
|
||||
:label="t('module.autoRecycle')"
|
||||
>
|
||||
<n-radio-group v-model:value="form.autoRecycle" name="radiogroup">
|
||||
<n-space>
|
||||
<n-radio key="yes" :value="true">
|
||||
{{ t('common.yes') }}
|
||||
</n-radio>
|
||||
<n-radio key="no" :value="false">
|
||||
{{ t('common.no') }}
|
||||
</n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
require-mark-placement="left"
|
||||
label-placement="left"
|
||||
path="expirationReminder"
|
||||
:label="t('module.expirationReminder')"
|
||||
>
|
||||
<n-radio-group v-model:value="form.expirationReminder" name="radiogroup">
|
||||
<n-space>
|
||||
<n-radio key="yes" :value="true">
|
||||
{{ t('common.yes') }}
|
||||
</n-radio>
|
||||
<n-radio key="no" :value="false">
|
||||
{{ t('common.no') }}
|
||||
</n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</CrmDrawer>
|
||||
</template>
|
||||
@@ -162,46 +126,98 @@
|
||||
NForm,
|
||||
NFormItem,
|
||||
NInput,
|
||||
NInputNumber,
|
||||
NRadio,
|
||||
NRadioGroup,
|
||||
NSelect,
|
||||
NSpace,
|
||||
SelectOption,
|
||||
useMessage,
|
||||
} from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import CrmDrawer from '@/components/pure/crm-drawer/index.vue';
|
||||
import CrmBatchForm from '@/components/business/crm-batch-form/index.vue';
|
||||
import type { FormItemModel } from '@/components/business/crm-batch-form/types';
|
||||
import { FieldTypeEnum } from '@/components/business/crm-form-create/enum';
|
||||
import CrmUserSelect from '@/components/business/crm-user-select/index.vue';
|
||||
import { SelectedUsersItem } from '@/components/business/crm-select-user-drawer/type';
|
||||
import CrmUserTagSelector from '@/components/business/crm-user-tag-selector/index.vue';
|
||||
|
||||
import { getUserOptions } from '@/api/modules/system/org';
|
||||
import { addOpportunityRule, updateOpportunityRule } from '@/api/modules/system/module';
|
||||
import { EQUAL, GE, GT, LE, LT, NOT_EQUAL } from '@/config/operator';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
import { OperatorEnum } from '@lib/shared/enums/commonEnum';
|
||||
import type { ModuleConditionsItem, OpportunityDetail, OpportunityParams } from '@lib/shared/models/system/module';
|
||||
|
||||
const { t } = useI18n();
|
||||
const Message = useMessage();
|
||||
|
||||
export type OpportunityDetailType = {
|
||||
ownerIds: SelectedUsersItem[];
|
||||
scopeIds: SelectedUsersItem[];
|
||||
} & OpportunityDetail;
|
||||
|
||||
const props = defineProps<{
|
||||
rows?: OpportunityDetailType;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'loadList'): void;
|
||||
(e: 'cancel'): void;
|
||||
}>();
|
||||
|
||||
const visible = defineModel<boolean>('visible', {
|
||||
required: true,
|
||||
});
|
||||
|
||||
const adminOptions = ref([]);
|
||||
|
||||
const rules: FormRules = {
|
||||
ruleName: [{ required: true, message: t('common.notNull', { value: `${t('org.userName')}` }) }],
|
||||
adminId: [{ required: true, message: t('common.pleaseSelect') }],
|
||||
userId: [{ required: true, message: t('common.pleaseSelect') }],
|
||||
reminderAdvance: [{ required: true, message: t('common.pleaseInput') }],
|
||||
name: [{ required: true, message: t('common.notNull', { value: `${t('org.userName')}` }) }],
|
||||
ownerIds: [{ required: true, message: t('common.pleaseSelect') }],
|
||||
scopeIds: [{ required: true, message: t('common.pleaseSelect') }],
|
||||
noticeDays: [{ required: true, message: t('common.pleaseInput') }],
|
||||
};
|
||||
|
||||
const closeAttrsOptions = ref<SelectOption[]>([
|
||||
{
|
||||
value: 'belongDays',
|
||||
label: t('opportunity.belongDays'),
|
||||
},
|
||||
{
|
||||
value: 'remainingDays',
|
||||
label: t('module.remainingDays'),
|
||||
},
|
||||
{
|
||||
value: 'opportunityStage',
|
||||
label: t('opportunity.opportunityStage'),
|
||||
},
|
||||
]);
|
||||
|
||||
const formItemModel: Ref<FormItemModel[]> = ref([
|
||||
{
|
||||
path: 'member',
|
||||
type: FieldTypeEnum.INPUT,
|
||||
path: 'column',
|
||||
type: FieldTypeEnum.SELECT,
|
||||
rule: [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.pleaseSelect'),
|
||||
},
|
||||
],
|
||||
selectProps: {
|
||||
options: closeAttrsOptions.value,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'operator',
|
||||
type: FieldTypeEnum.INPUT,
|
||||
type: FieldTypeEnum.SELECT,
|
||||
rule: [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.pleaseSelect'),
|
||||
},
|
||||
],
|
||||
selectProps: {
|
||||
options: [EQUAL, NOT_EQUAL, GT, GE, LT, LE],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'value',
|
||||
@@ -209,51 +225,100 @@
|
||||
},
|
||||
]);
|
||||
|
||||
// TODO 类型
|
||||
const form = ref({
|
||||
id: '',
|
||||
ruleName: '',
|
||||
adminId: null,
|
||||
userId: null,
|
||||
autoClose: true,
|
||||
expirationReminder: true,
|
||||
reminderAdvance: '1',
|
||||
autoRecycle: true,
|
||||
list: [],
|
||||
});
|
||||
const initDefaultItem: ModuleConditionsItem = {
|
||||
column: 'belongDays',
|
||||
operator: OperatorEnum.EQ,
|
||||
value: '',
|
||||
};
|
||||
|
||||
const initRuleForm: OpportunityDetailType = {
|
||||
name: '',
|
||||
auto: false,
|
||||
enable: true,
|
||||
expireNotice: false,
|
||||
noticeDays: 0,
|
||||
conditions: [initDefaultItem],
|
||||
operator: 'AND',
|
||||
ownerIds: [],
|
||||
scopeIds: [],
|
||||
};
|
||||
|
||||
const form = ref<OpportunityDetailType>(cloneDeep(initRuleForm));
|
||||
|
||||
function cancelHandler() {
|
||||
form.value.userId = null;
|
||||
form.value = cloneDeep(initRuleForm);
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
const formRef = ref<FormInst | null>(null);
|
||||
const loading = ref<boolean>(false);
|
||||
function confirmHandler(isContinue: boolean) {
|
||||
formRef.value?.validate(async (error) => {
|
||||
if (!error) {
|
||||
try {
|
||||
loading.value = true;
|
||||
if (form.value.id) {
|
||||
Message.success(t('common.updateSuccess'));
|
||||
} else {
|
||||
Message.success(t('common.addSuccess'));
|
||||
}
|
||||
|
||||
if (isContinue) {
|
||||
// TODO
|
||||
} else {
|
||||
cancelHandler();
|
||||
}
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(e);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
const batchFormRef = ref<InstanceType<typeof CrmBatchForm>>();
|
||||
|
||||
function userFormValidate(cb: (_isContinue: boolean) => Promise<any>, isContinue: boolean) {
|
||||
batchFormRef.value?.formValidate(async (batchForm?: Record<string, any>) => {
|
||||
try {
|
||||
loading.value = true;
|
||||
form.value.conditions = batchForm?.list;
|
||||
form.value.operator = batchForm?.allOr;
|
||||
await cb(isContinue);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function handleSave(isContinue: boolean) {
|
||||
try {
|
||||
loading.value = true;
|
||||
const { ownerIds, scopeIds } = form.value;
|
||||
const params: OpportunityParams = {
|
||||
...form.value,
|
||||
ownerIds: ownerIds.map((e) => e.id),
|
||||
scopeIds: scopeIds.map((e) => e.id),
|
||||
};
|
||||
|
||||
if (form.value.id) {
|
||||
await updateOpportunityRule(params);
|
||||
Message.success(t('common.updateSuccess'));
|
||||
} else {
|
||||
await addOpportunityRule(params);
|
||||
Message.success(t('common.addSuccess'));
|
||||
}
|
||||
if (isContinue) {
|
||||
form.value = cloneDeep(initRuleForm);
|
||||
} else {
|
||||
cancelHandler();
|
||||
}
|
||||
emit('loadList');
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(e);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function confirmHandler(isContinue: boolean) {
|
||||
formRef.value?.validate(async (error) => {
|
||||
if (!error) {
|
||||
userFormValidate(handleSave, isContinue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.rows,
|
||||
(val) => {
|
||||
if (val) {
|
||||
// TODO 回显待联调
|
||||
form.value = cloneDeep(val);
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
|
||||
@@ -12,4 +12,6 @@ export default {
|
||||
'opportunity.gotIt': 'Got it',
|
||||
'opportunity.goMove': 'To transfer',
|
||||
'opportunity.clueRecoveryRule': 'Clue Recovery Rule',
|
||||
'opportunity.belongDays': 'Belong Days',
|
||||
'opportunity.opportunityStage': 'Opportunity stage',
|
||||
};
|
||||
|
||||
@@ -11,4 +11,6 @@ export default {
|
||||
'opportunity.gotIt': '知道了',
|
||||
'opportunity.goMove': '去转移',
|
||||
'opportunity.clueRecoveryRule': '线索回收规则',
|
||||
'opportunity.belongDays': '归属天数',
|
||||
'opportunity.opportunityStage': '商机阶段',
|
||||
};
|
||||
|
||||
@@ -9,9 +9,12 @@
|
||||
>
|
||||
<div class="business-close-rule">
|
||||
<div class="h-full bg-[var(--text-n10)] p-[16px]">
|
||||
<n-button class="mb-[16px] mr-[12px]" type="primary" @click="addRule">
|
||||
{{ t('module.businessManage.addRules') }}
|
||||
</n-button>
|
||||
<div class="mb-[16px] flex items-center justify-between">
|
||||
<n-button class="mr-[12px]" type="primary" @click="addRule">
|
||||
{{ t('module.businessManage.addRules') }}
|
||||
</n-button>
|
||||
<CrmSearchInput v-model:value="keyword" class="!w-[240px]" @search="searchData" />
|
||||
</div>
|
||||
<CrmTable
|
||||
v-bind="propsRes"
|
||||
@page-change="propsEvent.pageChange"
|
||||
@@ -20,7 +23,12 @@
|
||||
@filter-change="propsEvent.filterChange"
|
||||
/>
|
||||
</div>
|
||||
<AddRuleDrawer v-model:visible="showAddRuleDrawer" />
|
||||
<AddRuleDrawer
|
||||
v-model:visible="showAddRuleDrawer"
|
||||
:rows="ruleRecord"
|
||||
@load-list="initOpportunityList()"
|
||||
@cancel="handleCancel"
|
||||
/>
|
||||
</div>
|
||||
</CrmDrawer>
|
||||
</template>
|
||||
@@ -31,19 +39,20 @@
|
||||
|
||||
import CrmDrawer from '@/components/pure/crm-drawer/index.vue';
|
||||
import CrmNameTooltip from '@/components/pure/crm-name-tooltip/index.vue';
|
||||
import CrmSearchInput from '@/components/pure/crm-search-input/index.vue';
|
||||
import CrmTable from '@/components/pure/crm-table/index.vue';
|
||||
import type { CrmTableDataItem } from '@/components/pure/crm-table/type';
|
||||
import { CrmDataTableColumn } from '@/components/pure/crm-table/type';
|
||||
import useTable from '@/components/pure/crm-table/useTable';
|
||||
import CrmOperationButton from '@/components/business/crm-operation-button/index.vue';
|
||||
import AddRuleDrawer from './addRuleDrawer.vue';
|
||||
|
||||
import { getOpportunityList } from '@/api/modules/system/module';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
||||
import type { OpportunityDetailType } from './addRuleDrawer.vue';
|
||||
import { TableKeyEnum } from '@lib/shared/enums/tableEnum';
|
||||
import type { CommonList } from '@lib/shared/models/common';
|
||||
|
||||
const { openModal } = useModal();
|
||||
const Message = useMessage();
|
||||
@@ -54,6 +63,8 @@
|
||||
required: true,
|
||||
});
|
||||
|
||||
const keyword = ref<string>('');
|
||||
|
||||
const groupList = ref([
|
||||
{
|
||||
label: t('common.edit'),
|
||||
@@ -65,7 +76,9 @@
|
||||
},
|
||||
]);
|
||||
|
||||
// TODO 等待联调
|
||||
function addOrEditRule(row: any) {}
|
||||
|
||||
// 删除规则
|
||||
function deleteRule(row: any) {
|
||||
const hasData = false;
|
||||
@@ -244,38 +257,7 @@
|
||||
},
|
||||
];
|
||||
|
||||
function initData() {
|
||||
const data: CommonList<CrmTableDataItem<any>> = {
|
||||
total: 11,
|
||||
pageSize: 10,
|
||||
current: 1,
|
||||
list: [
|
||||
{
|
||||
id: '11',
|
||||
num: 'string',
|
||||
title: 'string',
|
||||
enable: false,
|
||||
updateTime: null,
|
||||
createTime: null,
|
||||
},
|
||||
{
|
||||
id: '22',
|
||||
num: '232324323',
|
||||
title: '222',
|
||||
enable: false,
|
||||
updateTime: null,
|
||||
createTime: null,
|
||||
},
|
||||
],
|
||||
};
|
||||
return new Promise<CommonList<CrmTableDataItem<any>>>((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(data);
|
||||
}, 200);
|
||||
});
|
||||
}
|
||||
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(initData, {
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(getOpportunityList, {
|
||||
tableKey: TableKeyEnum.MODULE_OPPORTUNITY_RULE_TABLE,
|
||||
showSetting: true,
|
||||
columns,
|
||||
@@ -283,10 +265,27 @@
|
||||
});
|
||||
|
||||
const showAddRuleDrawer = ref<boolean>(false);
|
||||
const ruleRecord = ref<OpportunityDetailType>();
|
||||
function addRule() {
|
||||
showAddRuleDrawer.value = true;
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
ruleRecord.value = undefined;
|
||||
}
|
||||
|
||||
function initOpportunityList() {
|
||||
setLoadListParams({
|
||||
keyword: keyword.value,
|
||||
});
|
||||
loadList();
|
||||
}
|
||||
|
||||
function searchData(val: string) {
|
||||
keyword.value = val;
|
||||
initOpportunityList();
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
loadList();
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@ export default {
|
||||
'After closing, members will not find the module in the main navigation, please be careful!',
|
||||
'module.openModuleTip': 'Confirm to open module {name}?',
|
||||
'module.openModuleTipContent': 'After opening, the module appears in the main navigation menu',
|
||||
'module.remainingDays': 'Remaining ownership days',
|
||||
'module.customer.openSea': 'Public Sea Settings',
|
||||
'module.customer.capacitySet': 'Customer capacity settings',
|
||||
'module.clue': 'Clue Pool',
|
||||
|
||||
@@ -12,6 +12,7 @@ export default {
|
||||
'module.closeModuleTipContent': '关闭后,成员在主导航找不到该模块,请谨慎操作!',
|
||||
'module.openModuleTip': '确认开启模块 {name} 吗',
|
||||
'module.openModuleTipContent': '模块开启后,模块出现在主导航菜单',
|
||||
'module.remainingDays': '剩余归属天数',
|
||||
'module.customer.openSea': '公海设置',
|
||||
'module.customer.capacitySet': '客户库容设置',
|
||||
'module.clue': '线索池',
|
||||
|
||||
@@ -690,14 +690,14 @@
|
||||
tooltip: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('org.userGroup'),
|
||||
key: 'userGroup',
|
||||
width: 100,
|
||||
ellipsis: {
|
||||
tooltip: true,
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: t('org.userGroup'),
|
||||
// key: 'userGroup',
|
||||
// width: 100,
|
||||
// ellipsis: {
|
||||
// tooltip: true,
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: t('common.createTime'),
|
||||
key: 'createTime',
|
||||
@@ -763,6 +763,8 @@
|
||||
position: row.position || '-',
|
||||
departmentName: row.departmentName || '-',
|
||||
workCity: getCityPath(row.workCity) || '-',
|
||||
phone: row.phone || '-',
|
||||
email: row.email || '-',
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user