parent
b455947c6a
commit
e2c1376608
45 changed files with 198 additions and 841 deletions
@ -1,84 +1,81 @@ |
|||||||
import axios from '@/utils/request'; |
import axios from '@/utils/request'; |
||||||
|
import { getIds } from '@/utils/common'; |
||||||
|
|
||||||
export const accessStrategyGovernmentBlacklistFind = async (checkpointId: number, projectId: number): Promise<any> => |
const host = `http://192.168.31.51:9000`; |
||||||
(await axios.post(`/product/accessStrategyGovernmentBlacklist/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
|
export const accessStrategyGovernmentBlacklistFind = async (): Promise<any> => (await axios.post(`/product/accessStrategyGovernmentBlacklist/details`, getIds())).data; |
||||||
export const accessStrategyGovernmentBlacklistSave = async (data: Record<string, any>): Promise<any> => |
export const accessStrategyGovernmentBlacklistSave = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/accessStrategyGovernmentBlacklist/saveOrUpdate`, data)).data; |
(await axios.post(`/product/accessStrategyGovernmentBlacklist/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const accessStrategyEnterpriseBlacklistFind = async (checkpointId: number, projectId: number): Promise<any> => |
export const accessStrategyEnterpriseBlacklistFind = async (): Promise<any> => (await axios.post(`/product/accessStrategyEnterpriseBlacklist/details`, getIds())).data; |
||||||
(await axios.post(`/product/accessStrategyEnterpriseBlacklist/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const accessStrategyEnterpriseBlacklistSave = async (data: Record<string, any>): Promise<any> => |
export const accessStrategyEnterpriseBlacklistSave = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/accessStrategyEnterpriseBlacklist/saveOrUpdate`, data)).data; |
(await axios.post(`/product/accessStrategyEnterpriseBlacklist/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const accessStrategyAntiFraudStrategyFind = async (checkpointId: number, projectId: number): Promise<any> => |
export const accessStrategyAntiFraudStrategyFind = async (): Promise<any> => (await axios.post(`/product/accessStrategyAntiFraudStrategy/details`, getIds())).data; |
||||||
(await axios.post(`/product/accessStrategyAntiFraudStrategy/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const accessStrategyAntiFraudStrategySave = async (data: Record<string, any>): Promise<any> => |
export const accessStrategyAntiFraudStrategySave = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/accessStrategyAntiFraudStrategy/saveOrUpdate`, data)).data; |
(await axios.post(`/product/accessStrategyAntiFraudStrategy/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const accessStrategyBusinessBlacklistFind = async (checkpointId: number, projectId: number): Promise<any> => |
export const accessStrategyBusinessBlacklistFind = async (): Promise<any> => (await axios.post(`/product/accessStrategyBusinessBlacklist/details`, getIds())).data; |
||||||
(await axios.post(`/product/accessStrategyBusinessBlacklist/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const accessStrategyBusinessBlacklistSave = async (data: Record<string, any>): Promise<any> => |
export const accessStrategyBusinessBlacklistSave = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/accessStrategyBusinessBlacklist/saveOrUpdate`, data)).data; |
(await axios.post(`/product/accessStrategyBusinessBlacklist/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const accessStrategyCreditBlacklistFind = async (checkpointId: number, projectId: number): Promise<any> => |
export const accessStrategyCreditBlacklistFind = async (): Promise<any> => (await axios.post(`/product/accessStrategyCreditBlacklist/details`, getIds())).data; |
||||||
(await axios.post(`/product/accessStrategyCreditBlacklist/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const accessStrategyCreditBlacklistSave = async (data: Record<string, any>): Promise<any> => |
export const accessStrategyCreditBlacklistSave = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/accessStrategyCreditBlacklist/saveOrUpdate`, data)).data; |
(await axios.post(`/product/accessStrategyCreditBlacklist/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const accessStrategyInlineBlacklistFind = async (checkpointId: number, projectId: number): Promise<any> => |
export const accessStrategyInlineBlacklistFind = async (): Promise<any> => (await axios.post(`/product/accessStrategyInlineBlacklist/details`, getIds())).data; |
||||||
(await axios.post(`/product/accessStrategyInlineBlacklist/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const accessStrategyInlineBlacklistSave = async (data: Record<string, any>): Promise<any> => |
export const accessStrategyInlineBlacklistSave = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/accessStrategyInlineBlacklist/saveOrUpdate`, data)).data; |
(await axios.post(`/product/accessStrategyInlineBlacklist/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const accessStrategyNegativeIndustryStrategyFind = async (checkpointId: number, projectId: number): Promise<any> => |
export const accessStrategyNegativeIndustryStrategyFind = async (): Promise<any> => (await axios.post(`/product/accessStrategyNegativeIndustryStrategy/details`, getIds())).data; |
||||||
(await axios.post(`/product/accessStrategyNegativeIndustryStrategy/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const accessStrategyNegativeIndustryStrategySave = async (data: Record<string, any>): Promise<any> => |
export const accessStrategyNegativeIndustryStrategySave = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/accessStrategyNegativeIndustryStrategy/saveOrUpdate`, data)).data; |
(await axios.post(`/product/accessStrategyNegativeIndustryStrategy/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const delCredit = async (id: number): Promise<any> => (await axios.post(`/product/creditScoringStrategy/delete?strategyId=${id}`)).data; |
export const delCredit = async (id: number): Promise<any> => (await axios.post(`/product/creditScoringStrategy/delete?strategyId=${id}`)).data; |
||||||
export const findCredit = async (id: number): Promise<any> => (await axios.post(`/product/creditScoringStrategy/details?strategyId=${id}`)).data; |
export const findCredit = async (id: number): Promise<any> => (await axios.post(`/product/creditScoringStrategy/details?strategyId=${id}`)).data; |
||||||
export const listCredit = async (data: Record<string, any>): Promise<any> => |
export const listCredit = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/creditScoringStrategy/list?checkpointId=${data.checkpointId}&projectId=${data.projectId}&pageNum=${data.pageNum}&pageSize=${data.pageSize}`)).data; |
( |
||||||
|
await axios.post(`/product/creditScoringStrategy/list`, { |
||||||
|
...data, |
||||||
|
...getIds(), |
||||||
|
}) |
||||||
|
).data; |
||||||
export const saveCredit = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/creditScoringStrategy/saveOrUpdate`, data)).data; |
export const saveCredit = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/creditScoringStrategy/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const detailRick = async (data: Record<string, any>): Promise<any> => |
export const detailRick = async (type: number): Promise<any> => |
||||||
(await axios.post(`/product/riskDegreeStrategy/details?checkpointId=${data.checkpointId}&projectId=${data.projectId}&type=${data.type}`)).data; |
( |
||||||
|
await axios.post(`/product/riskDegreeStrategy/details`, { |
||||||
|
...getIds(), |
||||||
|
type, |
||||||
|
}) |
||||||
|
).data; |
||||||
export const saveRick = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/riskDegreeStrategy/saveOrUpdate`, data)).data; |
export const saveRick = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/riskDegreeStrategy/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const businessInterestRateDetails = async (checkpointId: number, projectId: number): Promise<any> => |
export const businessInterestRateDetails = async (): Promise<any> => (await axios.post(`/product/interestRateModel/businessInterestRateDetails`, getIds())).data; |
||||||
(await axios.post(`/product/interestRateModel/businessInterestRateDetails?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const businessInterestRateSaveOrUpdate = async (data: Record<string, any>): Promise<any> => |
export const businessInterestRateSaveOrUpdate = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/interestRateModel/businessInterestRateSaveOrUpdate`, data)).data; |
(await axios.post(`/product/interestRateModel/businessInterestRateSaveOrUpdate`, data)).data; |
||||||
export const personalInterestRateDetails = async (checkpointId: number, projectId: number): Promise<any> => |
export const personalInterestRateDetails = async (): Promise<any> => (await axios.post(`/product/interestRateModel/personalInterestRateDetails`, getIds())).data; |
||||||
(await axios.post(`/product/interestRateModel/personalInterestRateDetails?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const personalInterestRateSaveOrUpdate = async (data: Record<string, any>): Promise<any> => |
export const personalInterestRateSaveOrUpdate = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/interestRateModel/personalInterestRateSaveOrUpdate`, data)).data; |
(await axios.post(`/product/interestRateModel/personalInterestRateSaveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const businessQuotaModelDetails = async (checkpointId: number, projectId: number): Promise<any> => |
export const businessQuotaModelDetails = async (): Promise<any> => (await axios.post(`/product/quotaModel/businessQuotaModelDetails`, getIds())).data; |
||||||
(await axios.post(`/product/quotaModel/businessQuotaModelDetails?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const businessQuotaModelSaveOrUpdate = async (data: Record<string, any>): Promise<any> => |
export const businessQuotaModelSaveOrUpdate = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/quotaModel/businessQuotaModelSaveOrUpdate`, data)).data; |
(await axios.post(`/product/quotaModel/businessQuotaModelSaveOrUpdate`, data)).data; |
||||||
export const personalCreditModelDetails = async (checkpointId: number, projectId: number): Promise<any> => |
export const personalCreditModelDetails = async (): Promise<any> => (await axios.post(`/product/quotaModel/personalCreditModelDetails`, getIds())).data; |
||||||
(await axios.post(`/product/quotaModel/personalCreditModelDetails?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const personalCreditModelSaveOrUpdate = async (data: Record<string, any>): Promise<any> => |
export const personalCreditModelSaveOrUpdate = async (data: Record<string, any>): Promise<any> => |
||||||
(await axios.post(`/product/quotaModel/personalCreditModelSaveOrUpdate`, data)).data; |
(await axios.post(`/product/quotaModel/personalCreditModelSaveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const fiveLevelClassificationDetails = async (checkpointId: number, projectId: number): Promise<any> => |
export const fiveLevelClassificationDetails = async (): Promise<any> => (await axios.post(`/product/fiveLevelClassification/details`, getIds())).data; |
||||||
(await axios.post(`/product/fiveLevelClassification/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const fiveLevelClassificationSave = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/fiveLevelClassification/saveOrUpdate`, data)).data; |
export const fiveLevelClassificationSave = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/fiveLevelClassification/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const postLoanInspectionDetails = async (checkpointId: number, projectId: number): Promise<any> => |
export const postLoanInspectionDetails = async (): Promise<any> => (await axios.post(`/product/postLoanInspection/details`, getIds())).data; |
||||||
(await axios.post(`/product/postLoanInspection/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const postLoanInspectionSave = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/postLoanInspection/saveOrUpdate`, data)).data; |
export const postLoanInspectionSave = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/postLoanInspection/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const postCreditScoreDetails = async (checkpointId: number, projectId: number): Promise<any> => |
export const postCreditScoreDetails = async (): Promise<any> => (await axios.post(`/product/postCreditScore/details`, getIds())).data; |
||||||
(await axios.post(`/product/postCreditScore/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const postCreditScoreSave = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/postCreditScore/saveOrUpdate`, data)).data; |
export const postCreditScoreSave = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/postCreditScore/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const postLoanWarningDetails = async (checkpointId: number, projectId: number): Promise<any> => |
export const postLoanWarningDetails = async (): Promise<any> => (await axios.post(`/product/postLoanWarning/details`, getIds())).data; |
||||||
(await axios.post(`/product/postLoanWarning/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const postLoanWarningSave = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/postLoanWarning/saveOrUpdate`, data)).data; |
export const postLoanWarningSave = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/postLoanWarning/saveOrUpdate`, data)).data; |
||||||
|
|
||||||
export const collectionAfterLoanDetails = async (checkpointId: number, projectId: number): Promise<any> => |
export const collectionAfterLoanDetails = async (): Promise<any> => (await axios.post(`/product/collectionAfterLoan/details`, getIds())).data; |
||||||
(await axios.post(`/product/collectionAfterLoan/details?checkpointId=${checkpointId}&projectId=${projectId}`)).data; |
|
||||||
export const collectionAfterLoanSave = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/collectionAfterLoan/saveOrUpdate`, data)).data; |
export const collectionAfterLoanSave = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/collectionAfterLoan/saveOrUpdate`, data)).data; |
||||||
|
@ -1,258 +0,0 @@ |
|||||||
<template> |
|
||||||
<el-dialog |
|
||||||
:title="title" |
|
||||||
:close-on-click-modal="!unsaved" |
|
||||||
:model-value="modelValue" |
|
||||||
@update:model-value="$emit('update:modelValue', $event)" |
|
||||||
@opened="!isEdit && focus?.focus()" |
|
||||||
:width="large ? '98%' : '683px'" |
|
||||||
:top="large ? '16px' : undefined" |
|
||||||
> |
|
||||||
<div> |
|
||||||
<el-button v-if="isEdit && addable" :disabled="perm(`${perms}:create`)" type="primary" :icon="Plus" @click="handleAdd">{{ $t('add') }}</el-button> |
|
||||||
<el-popconfirm v-if="isEdit" :title="$t('confirmDelete')" @confirm="handleDelete"> |
|
||||||
<template #reference> |
|
||||||
<el-button :loading="buttonLoading" :disabled="disableDelete?.(bean) || perm(`${perms}:delete`)" :icon="Delete">{{ $t('delete') }}</el-button> |
|
||||||
</template> |
|
||||||
</el-popconfirm> |
|
||||||
<el-button v-if="isEdit" @click="handlePrev" :disabled="!hasPrev">{{ $t('form.prev') }}</el-button> |
|
||||||
<el-button v-if="isEdit" @click="handleNext" :disabled="!hasNext">{{ $t('form.next') }}</el-button> |
|
||||||
<el-button @click="handleCancel" type="primary">{{ $t('back') }}</el-button> |
|
||||||
<el-tooltip :content="$t('form.continuous')" placement="top"> |
|
||||||
<el-switch v-model="continuous" size="small" class="ml-2"></el-switch> |
|
||||||
</el-tooltip> |
|
||||||
<el-tag v-if="unsaved" type="danger" class="ml-2">{{ $t('form.unsaved') }}</el-tag> |
|
||||||
<slot name="header" :values="values" :bean="bean" :isEdit="isEdit"></slot> |
|
||||||
</div> |
|
||||||
<el-form |
|
||||||
:class="['mt-5', 'pr-5']" |
|
||||||
ref="form" |
|
||||||
v-loading="loading" |
|
||||||
:model="values" |
|
||||||
:disabled="!editable" |
|
||||||
:label-width="labelWidth ?? '150px'" |
|
||||||
:label-position="labelPosition ?? 'right'" |
|
||||||
> |
|
||||||
<slot :values="values" :bean="bean" :isEdit="isEdit"></slot> |
|
||||||
<div v-if="editable"> |
|
||||||
<el-button :disabled="perm(isEdit ? `${perms}:update` : `${perms}:create`)" :loading="buttonLoading" @click.prevent="handleSubmit" type="primary" native-type="submit"> |
|
||||||
{{ $t('submit') }} |
|
||||||
</el-button> |
|
||||||
</div> |
|
||||||
</el-form> |
|
||||||
</el-dialog> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script lang="ts"> |
|
||||||
import { computed, defineComponent, PropType, ref, toRefs, watch } from 'vue'; |
|
||||||
import { ElMessage } from 'element-plus'; |
|
||||||
import { Plus, Delete } from '@element-plus/icons-vue'; |
|
||||||
import { useI18n } from 'vue-i18n'; |
|
||||||
import _ from 'lodash'; |
|
||||||
import { perm } from '@/store/useCurrentUser'; |
|
||||||
|
|
||||||
const CONTINUOUS_SETTINGS = 'ujcms_continuous_settings'; |
|
||||||
function fetchContinuous(): Record<string, boolean> { |
|
||||||
const settings = localStorage.getItem(CONTINUOUS_SETTINGS); |
|
||||||
return settings ? JSON.parse(settings) : {}; |
|
||||||
} |
|
||||||
function storeContinuous(settings: Record<string, boolean>) { |
|
||||||
localStorage.setItem(CONTINUOUS_SETTINGS, JSON.stringify(settings)); |
|
||||||
} |
|
||||||
function getContinuous(name: string) { |
|
||||||
const settings = fetchContinuous(); |
|
||||||
return settings[name] ?? false; |
|
||||||
} |
|
||||||
function setContinuous(name: string, continuous: boolean) { |
|
||||||
const settings = fetchContinuous(); |
|
||||||
settings[name] = continuous; |
|
||||||
storeContinuous(settings); |
|
||||||
} |
|
||||||
|
|
||||||
export default defineComponent({ |
|
||||||
name: 'DialogForm', |
|
||||||
props: { |
|
||||||
modelValue: { type: Boolean, required: true }, |
|
||||||
name: { type: String, required: true }, |
|
||||||
beanId: { required: true }, |
|
||||||
beanIds: { type: Array, required: true }, |
|
||||||
initValues: { type: Function as PropType<(bean?: any) => any>, required: true }, |
|
||||||
toValues: { type: Function as PropType<(bean: any) => any>, required: true }, |
|
||||||
queryBean: { type: Function as PropType<(id: any) => Promise<any>>, required: true }, |
|
||||||
createBean: { type: Function as PropType<(bean: any) => Promise<any>>, required: true }, |
|
||||||
updateBean: { type: Function as PropType<(bean: any) => Promise<any>>, required: true }, |
|
||||||
deleteBean: { type: Function as PropType<(ids: any[]) => Promise<any>>, required: true }, |
|
||||||
disableDelete: { type: Function as PropType<(bean: any) => boolean> }, |
|
||||||
addable: { type: Boolean, default: true }, |
|
||||||
editable: { type: Boolean, default: true }, |
|
||||||
perms: String, |
|
||||||
focus: Object, |
|
||||||
large: Boolean, |
|
||||||
labelPosition: String, |
|
||||||
labelWidth: String, |
|
||||||
}, |
|
||||||
emits: { |
|
||||||
'update:modelValue': null, |
|
||||||
finished: null, |
|
||||||
beanChange: null, |
|
||||||
beforeSubmit: null, |
|
||||||
}, |
|
||||||
setup(props, { emit }) { |
|
||||||
const { name, beanId, beanIds, focus, modelValue: visible } = toRefs(props); |
|
||||||
const { t } = useI18n(); |
|
||||||
const loading = ref<boolean>(false); |
|
||||||
const buttonLoading = ref<boolean>(false); |
|
||||||
const continuous = ref<boolean>(getContinuous(name.value)); |
|
||||||
const reseted = ref<boolean>(false); |
|
||||||
const unsaved = ref<boolean>(false); |
|
||||||
const form = ref<any>(); |
|
||||||
const values = ref<any>(props.initValues()); |
|
||||||
const bean = ref<any>({}); |
|
||||||
const id = ref<any>(); |
|
||||||
const ids = ref<Array<any>>([]); |
|
||||||
const isEdit = computed(() => id.value != null); |
|
||||||
const title = computed(() => `${name.value} - ${isEdit.value ? `${t('edit')} (ID: ${id.value})` : `${t('add')}`}`); |
|
||||||
const idChanged = async () => { |
|
||||||
loading.value = true; |
|
||||||
unsaved.value = false; |
|
||||||
reseted.value = true; |
|
||||||
try { |
|
||||||
bean.value = id.value != null ? await props.queryBean(id.value) : {}; |
|
||||||
values.value = id.value != null ? props.toValues(bean.value) : props.initValues(values.value); |
|
||||||
emit('beanChange', bean.value); |
|
||||||
form.value.resetFields(); |
|
||||||
} finally { |
|
||||||
loading.value = false; |
|
||||||
} |
|
||||||
}; |
|
||||||
watch(visible, () => { |
|
||||||
if (visible.value) { |
|
||||||
ids.value = beanIds.value; |
|
||||||
if (id.value !== beanId.value) { |
|
||||||
id.value = beanId.value; |
|
||||||
} else if (id.value != null) { |
|
||||||
idChanged(); |
|
||||||
} |
|
||||||
if (id.value == null) { |
|
||||||
reseted.value = true; |
|
||||||
values.value = props.initValues(); |
|
||||||
} |
|
||||||
} |
|
||||||
}); |
|
||||||
watch(id, () => { |
|
||||||
idChanged(); |
|
||||||
}); |
|
||||||
watch( |
|
||||||
// 监听对象必须使用 lodash 的深度拷贝,才能在监听里面获取旧值和新值。 |
|
||||||
// 参考文档:https://v3.vuejs.org/guide/reactivity-computed-watchers.html#watching-reactive-objects |
|
||||||
() => _.cloneDeep(values.value), |
|
||||||
(curr, prev) => { |
|
||||||
// 重置触发的bean改动,不标记为未保存。 |
|
||||||
if (reseted.value) { |
|
||||||
reseted.value = false; |
|
||||||
} else if (JSON.stringify(curr) !== JSON.stringify(prev)) { |
|
||||||
// 自定义字段改变页面时,会改变values.customs,加上字段的值,但这些值为undefined。 |
|
||||||
// 这会触发watch监听,但json值不变。如json值不变,则不修改unsaved状态。 |
|
||||||
unsaved.value = true; |
|
||||||
} |
|
||||||
}, |
|
||||||
{ deep: true }, |
|
||||||
); |
|
||||||
watch(continuous, () => setContinuous(name.value, continuous.value)); |
|
||||||
const index = computed(() => ids.value.indexOf(id.value)); |
|
||||||
const hasPrev = computed(() => index.value > 0); |
|
||||||
const hasNext = computed(() => index.value < ids.value.length - 1); |
|
||||||
const handlePrev = () => { |
|
||||||
if (hasPrev.value) { |
|
||||||
id.value = ids.value[index.value - 1]; |
|
||||||
} |
|
||||||
}; |
|
||||||
const handleNext = () => { |
|
||||||
if (hasNext.value) { |
|
||||||
id.value = ids.value[index.value + 1]; |
|
||||||
} |
|
||||||
}; |
|
||||||
const handleAdd = () => { |
|
||||||
// eslint-disable-next-line no-unused-expressions |
|
||||||
focus?.value?.focus?.(); |
|
||||||
id.value = undefined; |
|
||||||
}; |
|
||||||
const handleCancel = () => { |
|
||||||
emit('update:modelValue', false); |
|
||||||
}; |
|
||||||
const handleSubmit = () => { |
|
||||||
form.value.validate(async (valid: boolean) => { |
|
||||||
if (!valid) return; |
|
||||||
buttonLoading.value = true; |
|
||||||
try { |
|
||||||
emit('beforeSubmit', values.value); |
|
||||||
if (isEdit.value) { |
|
||||||
await props.updateBean(values.value); |
|
||||||
unsaved.value = false; |
|
||||||
} else { |
|
||||||
await props.createBean(values.value); |
|
||||||
// eslint-disable-next-line no-unused-expressions |
|
||||||
focus?.value?.focus?.(); |
|
||||||
unsaved.value = false; |
|
||||||
reseted.value = true; |
|
||||||
values.value = props.initValues(values.value); |
|
||||||
form.value.resetFields(); |
|
||||||
} |
|
||||||
ElMessage.success(t('success')); |
|
||||||
if (!continuous.value) emit('update:modelValue', false); |
|
||||||
emit('finished', bean.value); |
|
||||||
} finally { |
|
||||||
buttonLoading.value = false; |
|
||||||
} |
|
||||||
}); |
|
||||||
}; |
|
||||||
const handleDelete = async () => { |
|
||||||
buttonLoading.value = true; |
|
||||||
try { |
|
||||||
await props.deleteBean([id.value]); |
|
||||||
if (!continuous.value) emit('update:modelValue', false); |
|
||||||
if (hasNext.value) { |
|
||||||
handleNext(); |
|
||||||
ids.value.splice(index.value - 1, 1); |
|
||||||
} else if (hasPrev.value) { |
|
||||||
handlePrev(); |
|
||||||
ids.value.splice(index.value + 1, 1); |
|
||||||
} else { |
|
||||||
emit('update:modelValue', false); |
|
||||||
} |
|
||||||
ElMessage.success(t('success')); |
|
||||||
emit('finished'); |
|
||||||
} finally { |
|
||||||
buttonLoading.value = false; |
|
||||||
} |
|
||||||
}; |
|
||||||
const setUnsaved = (bool: boolean) => { |
|
||||||
unsaved.value = bool; |
|
||||||
}; |
|
||||||
return { |
|
||||||
perm, |
|
||||||
handleAdd, |
|
||||||
handleDelete, |
|
||||||
handleSubmit, |
|
||||||
handleCancel, |
|
||||||
handlePrev, |
|
||||||
handleNext, |
|
||||||
hasPrev, |
|
||||||
hasNext, |
|
||||||
loading, |
|
||||||
buttonLoading, |
|
||||||
continuous, |
|
||||||
unsaved, |
|
||||||
isEdit, |
|
||||||
form, |
|
||||||
values, |
|
||||||
bean, |
|
||||||
id, |
|
||||||
title, |
|
||||||
setUnsaved, |
|
||||||
Plus, |
|
||||||
Delete, |
|
||||||
}; |
|
||||||
}, |
|
||||||
}); |
|
||||||
</script> |
|
@ -1,30 +0,0 @@ |
|||||||
<template> |
|
||||||
<p>{{ t('hello') }}</p> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script lang="ts"> |
|
||||||
import { defineComponent } from 'vue'; |
|
||||||
import { useI18n } from 'vue-i18n'; |
|
||||||
|
|
||||||
export default defineComponent({ |
|
||||||
name: 'HelloI18n', |
|
||||||
setup() { |
|
||||||
const { t } = useI18n({ |
|
||||||
inheritLocale: true, |
|
||||||
useScope: 'local', |
|
||||||
}); |
|
||||||
|
|
||||||
// Something todo .. |
|
||||||
|
|
||||||
return { t }; |
|
||||||
}, |
|
||||||
}); |
|
||||||
</script> |
|
||||||
|
|
||||||
<i18n> |
|
||||||
{ |
|
||||||
"en": { |
|
||||||
"hello": "Hello i18n in SFC!" |
|
||||||
} |
|
||||||
} |
|
||||||
</i18n> |
|
@ -1,17 +0,0 @@ |
|||||||
<template> |
|
||||||
{{ label ?? $t(message) }} |
|
||||||
<el-tooltip :content="tooltip ?? $t(message + '.tooltip')" |
|
||||||
placement="top"> |
|
||||||
<el-icon class="text-base align-text-top"><question-filled /></el-icon> |
|
||||||
</el-tooltip> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { QuestionFilled } from '@element-plus/icons-vue'; |
|
||||||
|
|
||||||
defineProps({ |
|
||||||
label: { type: String }, |
|
||||||
tooltip: { type: String }, |
|
||||||
message: { type: String, required: true }, |
|
||||||
}); |
|
||||||
</script> |
|
@ -1,27 +0,0 @@ |
|||||||
<template> |
|
||||||
<el-button-group> |
|
||||||
<el-button :disabled="disabled" |
|
||||||
:icon="Top" |
|
||||||
@click="$emit('move', 'top')">{{ $t('moveTop') }}</el-button> |
|
||||||
<el-button :disabled="disabled" |
|
||||||
:icon="ArrowUp" |
|
||||||
@click="$emit('move', 'up')">{{ $t('moveUp') }}</el-button> |
|
||||||
<el-button :disabled="disabled" |
|
||||||
:icon="ArrowDown" |
|
||||||
@click="$emit('move', 'down')">{{ $t('moveDown') }}</el-button> |
|
||||||
<el-button :disabled="disabled" |
|
||||||
:icon="Bottom" |
|
||||||
@click="$emit('move', 'bottom')">{{ $t('moveBottom') }}</el-button> |
|
||||||
</el-button-group> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { Top, Bottom, ArrowUp, ArrowDown } from '@element-plus/icons-vue'; |
|
||||||
|
|
||||||
defineProps({ |
|
||||||
disabled: { type: Boolean, required: true }, |
|
||||||
}); |
|
||||||
defineEmits({ |
|
||||||
move: null, |
|
||||||
}); |
|
||||||
</script> |
|
@ -1,59 +0,0 @@ |
|||||||
<template> |
|
||||||
<form class="flex"> |
|
||||||
<div class="space-y-1"> |
|
||||||
<div v-for="(name, index) in names" :key="name" class="flex"> |
|
||||||
<el-button :icon="index == 0 ? Plus : Minus" @click="handelRow(index)" :disabled="index <= 0 && remains.length <= 0" circle></el-button> |
|
||||||
<el-select v-model="names[index]" @change="clearParams()" class="w-36"> |
|
||||||
<el-option v-for="item in data.filter((it) => it.name === names[index] || remains.includes(it))" :key="item.name" :label="item.label" :value="item.name"></el-option> |
|
||||||
</el-select> |
|
||||||
<query-input :inputs="inputs" :name="names[index]"></query-input> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<div> |
|
||||||
<el-button-group class="ml-2"> |
|
||||||
<el-button native-type="submit" :icon="Search" @click.prevent="$emit('search')">{{ $t('search') }}</el-button> |
|
||||||
<el-button :icon="Refresh" @click="$emit('reset')">{{ $t('reset') }}</el-button> |
|
||||||
</el-button-group> |
|
||||||
</div> |
|
||||||
</form> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { defineEmits, useSlots, provide, computed, ref, toRefs } from 'vue'; |
|
||||||
import { Plus, Minus, Search, Refresh } from '@element-plus/icons-vue'; |
|
||||||
import QueryInput from './QueryInput.vue'; |
|
||||||
|
|
||||||
const props = defineProps({ params: { type: Object, required: true } }); |
|
||||||
const { params } = toRefs(props); |
|
||||||
const slots = useSlots(); |
|
||||||
provide('params', params); |
|
||||||
defineEmits({ |
|
||||||
search: null, |
|
||||||
reset: null, |
|
||||||
}); |
|
||||||
|
|
||||||
const data = ref<any[]>([]); |
|
||||||
const inputs = ref<any[]>([]); |
|
||||||
inputs.value = slots.default?.() ?? []; |
|
||||||
data.value = inputs.value.map((item) => ({ label: item.props?.label, name: item.props?.name })); |
|
||||||
|
|
||||||
const [first] = data.value; |
|
||||||
const names = ref<string[]>([first.name]); |
|
||||||
const remains = computed(() => data.value.filter((it) => !names.value.includes(it.name))); |
|
||||||
const clearParams = () => { |
|
||||||
Object.keys(params.value).forEach((key) => { |
|
||||||
if (!names.value.includes(key) && names.value.findIndex((item) => item.split(',').includes(key)) === -1) { |
|
||||||
delete params.value[key]; |
|
||||||
} |
|
||||||
}); |
|
||||||
}; |
|
||||||
const handelRow = (index: number) => { |
|
||||||
if (index === 0) { |
|
||||||
const [item] = remains.value; |
|
||||||
names.value[names.value.length] = item.name; |
|
||||||
} else { |
|
||||||
names.value.splice(index, 1); |
|
||||||
clearParams(); |
|
||||||
} |
|
||||||
}; |
|
||||||
</script> |
|
@ -1,16 +0,0 @@ |
|||||||
<script lang="ts"> |
|
||||||
import { defineComponent, computed, toRefs } from 'vue'; |
|
||||||
|
|
||||||
export default defineComponent({ |
|
||||||
name: 'QueryInput', |
|
||||||
props: { inputs: { type: Array, required: true }, name: { type: String, required: true } }, |
|
||||||
setup(props) { |
|
||||||
const { inputs, name } = toRefs(props); |
|
||||||
const input = computed(() => inputs.value.find((item: any) => item.props.name === name.value)); |
|
||||||
return { input }; |
|
||||||
}, |
|
||||||
render() { |
|
||||||
return this.input; |
|
||||||
}, |
|
||||||
}); |
|
||||||
</script> |
|
@ -1,64 +0,0 @@ |
|||||||
<template> |
|
||||||
<slot> |
|
||||||
<div v-if="type === 'number'" |
|
||||||
class="inline-block"> |
|
||||||
<el-input-number v-model="params[first]" |
|
||||||
:placeholder="$t('begin.number')" |
|
||||||
class="w-48"></el-input-number> |
|
||||||
<el-input-number v-model="params[second]" |
|
||||||
:placeholder="$t('end.number')" |
|
||||||
class="w-48"></el-input-number> |
|
||||||
</div> |
|
||||||
<el-date-picker v-else-if="type === 'date'" |
|
||||||
v-model="params[name]" |
|
||||||
type="daterange" |
|
||||||
:start-placeholder="$t('begin.date')" |
|
||||||
:end-placeholder="$t('end.date')" |
|
||||||
class="w-96"></el-date-picker> |
|
||||||
<el-date-picker v-else-if="type === 'datetime'" |
|
||||||
v-model="params[name]" |
|
||||||
type="datetimerange" |
|
||||||
:start-placeholder="$t('begin.date')" |
|
||||||
:end-placeholder="$t('end.date')" |
|
||||||
class="w-96"> |
|
||||||
</el-date-picker> |
|
||||||
<!-- |
|
||||||
<div v-else-if="type === 'date'" class="inline-block"> |
|
||||||
<el-date-picker v-model="params[first]" type="date" :placeholder="$t('begin.date')" class="w-48"></el-date-picker> |
|
||||||
<el-date-picker v-model="params[second]" type="date" :placeholder="$t('end.date')" class="w-48"></el-date-picker> |
|
||||||
</div> |
|
||||||
<div v-else-if="type === 'datetime'" class="inline-block"> |
|
||||||
<el-date-picker v-model="params[first]" type="datetime" class="w-48"></el-date-picker> |
|
||||||
<el-date-picker v-model="params[second]" type="datetime" class="w-48"></el-date-picker> |
|
||||||
</div> |
|
||||||
--> |
|
||||||
<el-select v-else-if="options" |
|
||||||
v-model="params[name]" |
|
||||||
multiple |
|
||||||
class="w-96"> |
|
||||||
<el-option v-for="item in options" |
|
||||||
:key="item.value" |
|
||||||
:label="item.label" |
|
||||||
:value="item.value"></el-option> |
|
||||||
</el-select> |
|
||||||
<el-input v-else |
|
||||||
v-model="params[name]" |
|
||||||
class="w-96"></el-input> |
|
||||||
</slot> |
|
||||||
</template> |
|
||||||
<script setup lang="ts"> |
|
||||||
import { inject, PropType, ref, toRefs } from 'vue'; |
|
||||||
|
|
||||||
const props = defineProps({ |
|
||||||
label: { type: String, required: true }, |
|
||||||
name: { type: String, required: true }, |
|
||||||
// 'string' | 'date' | 'datetime' | 'number' |
|
||||||
type: { type: String }, |
|
||||||
options: { type: Object as PropType<Array<{ label: string; value: string | number }>> }, |
|
||||||
}); |
|
||||||
const params = inject<any>('params'); |
|
||||||
const { name } = toRefs(props); |
|
||||||
const [firstName, secondName] = name.value.split(','); |
|
||||||
const first = ref<string>(firstName); |
|
||||||
const second = ref<string>(secondName); |
|
||||||
</script> |
|
@ -1,2 +0,0 @@ |
|||||||
export { default as QueryForm } from './QueryForm.vue'; |
|
||||||
export { default as QueryItem } from './QueryItem.vue'; |
|
@ -1,45 +0,0 @@ |
|||||||
<script lang="ts"> |
|
||||||
import { computed, defineComponent, toRefs } from 'vue'; |
|
||||||
import { useI18n } from 'vue-i18n'; |
|
||||||
import { ColumnState, getColumnSettings, setColumnOrigins } from './useColumns'; |
|
||||||
|
|
||||||
export default defineComponent({ |
|
||||||
name: 'ColumnList', |
|
||||||
props: { name: { type: String, required: true } }, |
|
||||||
setup(props, { slots }) { |
|
||||||
const { name } = toRefs(props); |
|
||||||
const { t } = useI18n(); |
|
||||||
const slotColumns = slots.default?.() ?? []; |
|
||||||
// 获取栏目名称 |
|
||||||
const getColumnTitle = (columnProps: any) => { |
|
||||||
// 如果是checkbox列,则名称为“选择框” |
|
||||||
if (columnProps?.type === 'selection') return t('table.selection'); |
|
||||||
return columnProps?.label; |
|
||||||
}; |
|
||||||
// 获取el-table-column的名称、是否显示 |
|
||||||
const origins: ColumnState[] = slotColumns.map((column) => ({ title: getColumnTitle(column.props), display: column.props?.display !== 'none' })); |
|
||||||
setColumnOrigins(name.value, origins); |
|
||||||
|
|
||||||
const settings = getColumnSettings(name.value); |
|
||||||
const columns = computed(() => |
|
||||||
slotColumns |
|
||||||
.filter((column) => { |
|
||||||
const matched = settings.value.find((item) => getColumnTitle(column.props) === item.title); |
|
||||||
return !matched || matched.display; |
|
||||||
}) |
|
||||||
.map((column) => ({ ...column, key: getColumnTitle(column.props) })) |
|
||||||
.sort((a, b) => { |
|
||||||
let indexA = settings.value.findIndex((item) => item.title === getColumnTitle(a)); |
|
||||||
if (indexA < 0) indexA = slotColumns.findIndex((item) => getColumnTitle(item) === getColumnTitle(a)); |
|
||||||
let indexB = settings.value.findIndex((item) => item.title === getColumnTitle(b)); |
|
||||||
if (indexB < 0) indexB = slotColumns.findIndex((item) => getColumnTitle(item) === getColumnTitle(b)); |
|
||||||
return indexA - indexB; |
|
||||||
}), |
|
||||||
); |
|
||||||
return { columns }; |
|
||||||
}, |
|
||||||
render() { |
|
||||||
return this.columns; |
|
||||||
}, |
|
||||||
}); |
|
||||||
</script> |
|
@ -1,40 +0,0 @@ |
|||||||
<template> |
|
||||||
<el-dropdown class="align-middle" |
|
||||||
trigger="click" |
|
||||||
:hide-on-click="false"> |
|
||||||
<el-tooltip :content="$t('table.columnsSetting')" |
|
||||||
placement="top"> |
|
||||||
<el-icon class="text-base"> |
|
||||||
<setting /> |
|
||||||
</el-icon> |
|
||||||
</el-tooltip> |
|
||||||
<template #dropdown> |
|
||||||
<el-dropdown-menu> |
|
||||||
<el-dropdown-item> |
|
||||||
<el-button @click="resetColumns" |
|
||||||
type="text">{{ $t('table.columnsReset') }}</el-button> |
|
||||||
</el-dropdown-item> |
|
||||||
<el-dropdown-item v-for="(column, index) in settings" |
|
||||||
:key="column.title" |
|
||||||
:divided="index === 0"> |
|
||||||
<el-checkbox v-model="column.display">{{ column.title }}</el-checkbox> |
|
||||||
</el-dropdown-item> |
|
||||||
</el-dropdown-menu> |
|
||||||
</template> |
|
||||||
</el-dropdown> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { toRefs, watch } from 'vue'; |
|
||||||
import { Setting } from '@element-plus/icons-vue'; |
|
||||||
import { getColumnOrigins, getColumnSettings, mergeColumns, storeColumnSettings } from './useColumns'; |
|
||||||
|
|
||||||
const props = defineProps({ name: { type: String, required: true } }); |
|
||||||
const { name } = toRefs(props); |
|
||||||
const settings = getColumnSettings(name.value); |
|
||||||
const origins = getColumnOrigins(name.value); |
|
||||||
watch(settings, () => storeColumnSettings(), { deep: true }); |
|
||||||
const resetColumns = () => { |
|
||||||
settings.value = mergeColumns([], origins.value); |
|
||||||
}; |
|
||||||
</script> |
|
@ -1,2 +0,0 @@ |
|||||||
export { default as ColumnSetting } from './ColumnSetting.vue'; |
|
||||||
export { default as ColumnList } from './ColumnList.vue'; |
|
@ -1,55 +0,0 @@ |
|||||||
import { reactive, toRef } from 'vue'; |
|
||||||
|
|
||||||
export interface ColumnState { |
|
||||||
title: string; |
|
||||||
display: boolean; |
|
||||||
} |
|
||||||
|
|
||||||
const COLUMN_SETTINGS = 'ujcms_column_settings'; |
|
||||||
|
|
||||||
function fetchColumnSettings(): Record<string, ColumnState[]> { |
|
||||||
const settings = localStorage.getItem(COLUMN_SETTINGS); |
|
||||||
return settings ? JSON.parse(settings) : {}; |
|
||||||
} |
|
||||||
|
|
||||||
const originStore: Record<string, ColumnState[]> = reactive({}); |
|
||||||
const settingStore: Record<string, ColumnState[]> = reactive(fetchColumnSettings()); |
|
||||||
|
|
||||||
export function storeColumnSettings() { |
|
||||||
localStorage.setItem(COLUMN_SETTINGS, JSON.stringify(settingStore)); |
|
||||||
} |
|
||||||
export const getColumnOrigins = (name: string) => { |
|
||||||
if (!originStore[name]) originStore[name] = []; |
|
||||||
return toRef(originStore, name); |
|
||||||
}; |
|
||||||
export const mergeColumns = (settings: ColumnState[], origins: ColumnState[]) => { |
|
||||||
// 去除不存在的列
|
|
||||||
for (let i = 0, len = settings.length; i < len; ) { |
|
||||||
if (origins.findIndex((column) => column.title === settings[i].title) === -1) { |
|
||||||
settings.splice(i, 1); |
|
||||||
len -= 1; |
|
||||||
} else { |
|
||||||
i += 1; |
|
||||||
} |
|
||||||
} |
|
||||||
// 增加未记录的列
|
|
||||||
origins.forEach((column) => { |
|
||||||
if (settings.findIndex((item) => item.title === column.title) === -1) { |
|
||||||
settings.push({ ...column }); |
|
||||||
} |
|
||||||
}); |
|
||||||
return settings; |
|
||||||
}; |
|
||||||
export const setColumnOrigins = (name: string, origins: ColumnState[]) => { |
|
||||||
originStore[name] = origins; |
|
||||||
if (!settingStore[name]) settingStore[name] = []; |
|
||||||
const settings = settingStore[name]; |
|
||||||
mergeColumns(settings, origins); |
|
||||||
}; |
|
||||||
export const getColumnSettings = (name: string) => { |
|
||||||
if (!settingStore[name]) settingStore[name] = []; |
|
||||||
return toRef(settingStore, name); |
|
||||||
}; |
|
||||||
// export const setColumnSettings = (name: string, settings: ColumnState[]) => {
|
|
||||||
// settingStore[name] = settings;
|
|
||||||
// };
|
|
Loading…
Reference in new issue