yujialong 1 year ago
parent 29d34de052
commit 978570f1e0
  1. 18
      src/layout/components/AppSidebar/index.vue
  2. 10
      src/settings.ts
  3. 16
      src/views/config/level/Index.vue
  4. 69
      src/views/product/bank/Config.vue
  5. 4
      src/views/product/bank/List.vue
  6. 4
      src/views/product/insurance/List.vue
  7. 20
      src/views/product/strategy/150.vue
  8. 49
      src/views/user/GroupForm.vue
  9. 158
      src/views/user/GroupList.vue
  10. 66
      src/views/user/RoleForm.vue
  11. 117
      src/views/user/RoleList.vue
  12. 248
      src/views/user/UserForm.vue
  13. 259
      src/views/user/UserList.vue

@ -5,8 +5,8 @@
<img class="mx-auto"
src="@/assets/images/6.png"
alt="" />
<p class="text-white text-md">产品经理</p>
<p class="my-2 text-white text-sm">产品经理</p>
<p class="text-white text-md">{{roleName}}</p>
<p class="my-2 text-white text-sm">产品部门</p>
<p class="text-white text-xs">操作日期2018-02-06</p>
</div>
<menus></menus>
@ -18,21 +18,19 @@
import { computed } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import Menus from './Menu.vue';
import Settings from '@/settings';
import { isShowMenu } from '@/store/useCurrentUser';
import { appState } from '@/store/useAppState';
const router = useRouter();
const route = useRoute();
// const routes = computed(() => router.options.routes);
const activeMenu = computed(() => {
const { meta, path } = route;
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu as string;
const roleName = computed(() => {
if (route.query.role) {
return Settings.roleIds[+route.query.role];
} else if (route.path.includes('insurance')) {
return '保险产品经理';
}
return path;
});
// Cool Gray 700

@ -1,7 +1,15 @@
export default {
title: import.meta.env.VITE_APP_TITLE || '金融产品设计及数字化营销沙盘',
showSettings: true,
/**
* @type {object}
* @description id
*/
roleIds: {
41: '产品经理',
42: '风控经理',
43: '专家委员会',
},
/**
* @type {array}
* @description

@ -42,8 +42,7 @@
</div>
<div class="h-[calc(100vh-270px)] overflow-auto"
id="tableWrap">
<el-table ref="tableRef"
v-loading="loading"
<el-table v-loading="loading"
:data="list"
@selection-change="handleSelectionChange">
<el-table-column label="移动"
@ -60,6 +59,7 @@
</template>
<div class="flex items-center mb-2">
<el-input class="w-[80px]"
placeholder="请输入"
v-model.number="row.serial"></el-input>
<el-icon class="ml-2 cursor-pointer"
:size="16"
@ -152,7 +152,7 @@
<script setup lang="ts">
import { computed, onMounted, ref, reactive, watch, nextTick } from 'vue';
import { ElMessage, ElTable } from 'element-plus';
import { ElMessage } from 'element-plus';
import { Delete, Edit, Check, MoreFilled, Close } from '@element-plus/icons-vue';
import { listPass, savePass, updatePass } from '@/api/config';
import Search from '@/components/Search.vue';
@ -164,14 +164,12 @@ const route = useRoute();
const projectId = +Cookies.get('sand-projectId');
const levelId = +Cookies.get('sand-level');
const height = window.innerHeight - 270;
const tableRef = ref<InstanceType<typeof ElTable>>();
const delTitle: string = '删除关卡后,这个关卡的数据将被删除,确定删除吗?';
const params = reactive({
platformId: 3,
customsPassName: '',
isEnable: '',
});
const table = ref<any>();
const enables = ref<Array<any>>([
{
id: 0,
@ -209,7 +207,10 @@ watch([params, () => route.query], getList);
const save = async () => {
if (saveLoading.value) return false;
saveLoading.value = true;
const param = list.value.map((e, i) => {
//
const param = list.value
.filter((e) => e.checkpointId)
.map((e, i) => {
e.serialNumber = i + 1;
return {
checkpointId: e.checkpointId,
@ -219,6 +220,9 @@ const save = async () => {
};
});
await updatePass(param);
//
const addList = list.value.filter((e) => !e.checkpointId);
await savePass(addList);
getList();
ElMessage.success('保存成功!');
saveLoading.value = false;

@ -140,10 +140,12 @@
class="ml-5"
v-model="form.personalCreditScoringStrategies"
placeholder="请选择">
<el-option v-for="item in config[2]?.recordChildren[2]?.subject?.itemList[0]?.children"
:key="item.itemId"
:label="item.options"
:value="item.itemId" />
<el-option v-for="item in credits.filter(e => !e.scoringObject)"
:key="item"
:label="item.scoreCardName"
:value="item.id" />
<el-option label="无"
:value="761" />
</el-select>
</div>
<div class="flex items-center">
@ -153,10 +155,12 @@
class="ml-5"
v-model="form.corporateCreditScoringStrategies"
placeholder="请选择">
<el-option v-for="item in config[2]?.recordChildren[2]?.subject?.itemList[1]?.children"
:key="item.itemId"
:label="item.options"
:value="item.itemId" />
<el-option v-for="item in credits.filter(e => e.scoringObject)"
:key="item"
:label="item.scoreCardName"
:value="item.id" />
<el-option label="无"
:value="761" />
</el-select>
</div>
</div>
@ -264,7 +268,7 @@
class="ml-5"
v-model="form.loanContract"
placeholder="请选择">
<el-option v-for="item in config[6]?.recordChildren[1]?.recordChildren"
<el-option v-for="item in config[6]?.recordChildren[1]?.recordChildren[0]?.subject?.itemList"
:key="item.itemId"
:label="item.options"
:value="item.itemId" />
@ -277,7 +281,7 @@
class="ml-5"
v-model="form.mortgageContract"
placeholder="请选择">
<el-option v-for="item in config[6]?.recordChildren[1]?.subject?.itemList[1]?.children"
<el-option v-for="item in config[6]?.recordChildren[1]?.recordChildren[1]?.subject?.itemList"
:key="item.itemId"
:label="item.options"
:value="item.itemId" />
@ -290,7 +294,7 @@
class="ml-5"
v-model="form.pledgeContract"
placeholder="请选择">
<el-option v-for="item in config[6]?.recordChildren[1]?.subject?.itemList[2]?.children"
<el-option v-for="item in config[6]?.recordChildren[1]?.recordChildren[2]?.subject?.itemList"
:key="item.itemId"
:label="item.options"
:value="item.itemId" />
@ -303,7 +307,7 @@
class="ml-5"
v-model="form.guaranteeContract"
placeholder="请选择">
<el-option v-for="item in config[6]?.recordChildren[1]?.subject?.itemList[3]?.children"
<el-option v-for="item in config[6]?.recordChildren[1]?.recordChildren[3]?.subject?.itemList"
:key="item.itemId"
:label="item.options"
:value="item.itemId" />
@ -345,6 +349,7 @@ import { ElMessage } from 'element-plus';
import type { TabsPaneContext, FormInstance } from 'element-plus';
import { findById, riskSave, riskUpdate } from '@/api/bank';
import { getProcessInformationBasedOnRoles, addOperation } from '@/api/judgment';
import { listCredit } from '@/api/model';
import { useRouter, useRoute } from 'vue-router';
import { handleId } from '@/utils/common';
import Info from './Info.vue';
@ -398,6 +403,7 @@ const projectId = +Cookies.get('sand-projectId');
const levelId = +Cookies.get('sand-level');
const curTab = ref<string>('tab1');
const config = ref<any[]>([]);
const credits = ref<Record<string, any>[]>([]);
const info = ref<Record<string, any>>({});
const formRef = ref<FormInstance>();
const form = reactive<RuleForm>({
@ -450,6 +456,14 @@ const tabChange = (tab: TabsPaneContext, event: Event) => {
const getConfig = async () => {
const { process } = await getProcessInformationBasedOnRoles(info.value.productType ? 71 : 70); // 7071
config.value = process;
const { data } = await listCredit({
checkpointId: levelId,
projectId,
pageNum: 1,
pageSize: 1000,
});
credits.value = data;
};
//
const getDetail = async () => {
@ -481,17 +495,17 @@ const submit = async (formEl: FormInstance | undefined) => {
const isEnterprise = info.value.productType === 1;
const param = JSON.parse(JSON.stringify(form));
if (((isEnterprise && param.borrowerMaterial?.includes(316)) || (!isEnterprise && param.borrowerMaterial?.includes(314))) && !param.borrowerMaterialSelect)
return ElMessage.error('请选择借款申请表');
if (
(param.personalCreditScoringStrategiesCheck && !param.personalCreditScoringStrategies) ||
(param.corporateCreditScoringStrategiesCheck && !param.corporateCreditScoringStrategies)
)
return ElMessage.error('请选择信用评分策略');
if (param.loanContractCheck && !param.loanContract) return ElMessage.error('请选择借贷合同');
if (param.mortgageContractCheck && !param.mortgageContract) return ElMessage.error('请选择抵押合同');
if (param.pledgeContractCheck && !param.pledgeContract) return ElMessage.error('请选择质押合同');
if (param.guaranteeContractCheck && !param.guaranteeContract) return ElMessage.error('请选择担保合同');
// if (((isEnterprise && param.borrowerMaterial?.includes(316)) || (!isEnterprise && param.borrowerMaterial?.includes(314))) && !param.borrowerMaterialSelect)
// return ElMessage.error('');
// if (
// (param.personalCreditScoringStrategiesCheck && !param.personalCreditScoringStrategies) ||
// (param.corporateCreditScoringStrategiesCheck && !param.corporateCreditScoringStrategies)
// )
// return ElMessage.error('');
// if (param.loanContractCheck && !param.loanContract) return ElMessage.error('');
// if (param.mortgageContractCheck && !param.mortgageContract) return ElMessage.error('');
// if (param.pledgeContractCheck && !param.pledgeContract) return ElMessage.error('');
// if (param.guaranteeContractCheck && !param.guaranteeContract) return ElMessage.error('');
param.accessStrategy = param.accessStrategy.join();
if ((isEnterprise && param.borrowerMaterial?.includes(316)) || (!isEnterprise && param.borrowerMaterial?.includes(314)))
@ -569,7 +583,9 @@ const addRecord = async (data: Record<string, any>) => {
handleId(127, 51, data.runBatchObject, preIds + ',114,127', 1),
handleId(128, 52, data.accessStrategy, preIds + ',114,128', 1),
);
data.personalCreditScoringStrategiesCheck && lcRule.push(handleId(129, 53, '240,' + data.personalCreditScoringStrategies, preIds + ',114,129', 1));
//
lcRule.push(handleId(1044, 302, data.personalCreditScoringStrategiesCheck ? 759 : 760, preIds + ',114,129,1046,1044', 1));
data.personalCreditScoringStrategies === 761 && lcRule.push(handleId(1045, 303, data.personalCreditScoringStrategies, preIds + ',114,129,1046,1045', 1));
data.corporateCreditScoringStrategiesCheck && lcRule.push(handleId(129, 53, '241,' + data.corporateCreditScoringStrategies, preIds + ',114,129', 1));
lcRule.push(handleId(130, 54, data.riskDegreeStrategy, preIds + ',114,130', 1));
@ -603,8 +619,9 @@ const addRecord = async (data: Record<string, any>) => {
handleId(83, 28, data.accessStrategy, preIds + ',74,83', 1),
);
lcRule.push(handleId(1044, 282, data.personalCreditScoringStrategiesCheck ? 683 : 684, preIds + ',74,1046,1044', 1));
// data.personalCreditScoringStrategiesCheck && lcRule.push(handleId(1045, 283, data.personalCreditScoringStrategies, preIds + ',74,1046,1045', 1));
//
lcRule.push(handleId(1044, 302, data.personalCreditScoringStrategiesCheck ? 759 : 760, preIds + ',74,84,1046,1044', 1));
data.personalCreditScoringStrategies === 761 && lcRule.push(handleId(1045, 303, data.personalCreditScoringStrategies, preIds + ',74,84,1046,1045', 1));
data.corporateCreditScoringStrategiesCheck && lcRule.push(handleId(84, 29, '95,' + data.corporateCreditScoringStrategies, preIds + ',74,84', 1));
lcRule.push(handleId(85, 30, data.riskDegreeStrategy, preIds + ',74,85', 1));

@ -131,7 +131,6 @@
<script setup lang="ts">
import { computed, onMounted, ref, reactive, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { useI18n } from 'vue-i18n';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
import { getProcessInformationBasedOnRoles } from '@/api/judgment';
import { bankingProductsList, batchDeletion } from '@/api/bank';
@ -140,7 +139,6 @@ import { useRouter, useRoute } from 'vue-router';
import Cookies from 'js-cookie';
import { productState, getExpertStatus, getStatus } from '@/store/useProduct';
const { t } = useI18n();
const router = useRouter();
const route = useRoute();
const productTypes = ref<number[]>([0, 1]);
@ -225,6 +223,6 @@ const toCardList = () => {
const handleDelete = async (id: number) => {
await batchDeletion([id]);
getList();
ElMessage.success(t('success'));
ElMessage.success('删除成功!');
};
</script>

@ -105,7 +105,6 @@
<script setup lang="ts">
import { computed, onMounted, ref, reactive, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { useI18n } from 'vue-i18n';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
import { insuranceList, batchDeletion } from '@/api/insurance';
import Search from '@/components/Search.vue';
@ -113,7 +112,6 @@ import { useRouter, useRoute } from 'vue-router';
import Cookies from 'js-cookie';
import { productState, getExpertStatus, getStatus } from '@/store/useProduct';
const { t } = useI18n();
const router = useRouter();
const route = useRoute();
const projectId = +Cookies.get('sand-projectId');
@ -190,6 +188,6 @@ const toCardList = () => {
const handleDelete = async (id: number) => {
await batchDeletion([id]);
getList();
ElMessage.success(t('success'));
ElMessage.success('删除成功!');
};
</script>

@ -105,6 +105,14 @@
<el-checkbox v-model="row.corporateMajorityHitRejected"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="本人及亲属企业命中准入"
width="160"
align="center">
<template #default="{ row }">
<el-checkbox v-model="row.hitAccess"
@change="checkNone(row)"></el-checkbox>
</template>
</el-table-column>
</el-table>
<div class="flex justify-end">
@ -163,6 +171,7 @@ const getConfig = async () => {
recordChildren: e.recordChildren,
isRule: isRule(e.id) ? 1 : 0,
corporateMajorityHitRejected: !!cur?.corporateMajorityHitRejected,
hitAccess: !!cur?.hitAccess,
mateHitRejected: !!cur?.mateHitRejected,
otherFamilyMembersHitRejected: !!cur?.otherFamilyMembersHitRejected,
parentsHitRejected: !!cur?.parentsHitRejected,
@ -236,12 +245,22 @@ const span = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => {
}
}
};
const checkNone = (row: Record<string, any>) => {
if (row.hitAccess) {
row.corporateMajorityHitRejected = false;
row.mateHitRejected = false;
row.otherFamilyMembersHitRejected = false;
row.parentsHitRejected = false;
row.personalHitBlacklist = false;
}
};
//
const submit = async () => {
let param = JSON.parse(JSON.stringify(form.value));
param.map((e, i) => {
if (info.value.length) e.id = info.value.find((n) => n.stRecordId === e.stRecordId)?.id;
e.corporateMajorityHitRejected = +e.corporateMajorityHitRejected;
e.hitAccess = +e.hitAccess;
e.mateHitRejected = +e.mateHitRejected;
e.otherFamilyMembersHitRejected = +e.otherFamilyMembersHitRejected;
e.parentsHitRejected = +e.parentsHitRejected;
@ -288,6 +307,7 @@ const addRecord = async (data: Record<string, any>) => {
e.parentsHitRejected && temp.push(302);
e.otherFamilyMembersHitRejected && temp.push(303);
e.corporateMajorityHitRejected && temp.push(304);
e.hitAccess && temp.push(757);
if (isRule(e.stRecordId)) {
const len = e?.recordChildren?.length - 1;
e?.recordChildren.map((n, j) => {

@ -1,49 +0,0 @@
<template>
<dialog-form
:name="$t('menu.user.group')"
:queryBean="queryGroup"
:createBean="createGroup"
:updateBean="updateGroup"
:deleteBean="deleteGroup"
:beanId="beanId"
:beanIds="beanIds"
:focus="focus"
:initValues="() => ({ type: 2 })"
:toValues="(bean) => ({ ...bean })"
:disableDelete="(bean) => bean.id <= 10"
perms="group"
:model-value="modelValue"
@update:model-value="$emit('update:modelValue', $event)"
@finished="$emit('finished')"
>
<template #default="{ values }">
<el-form-item prop="name" :label="$t('group.name')" :rules="{ required: true, message: () => $t('v.required') }">
<el-input v-model="values.name" ref="focus" maxlength="50"></el-input>
</el-form-item>
<el-form-item prop="description" :label="$t('group.description')">
<el-input v-model="values.description" maxlength="255"></el-input>
</el-form-item>
<el-form-item prop="type" :label="$t('group.type')" :rules="{ required: true, message: () => $t('v.required') }">
<el-select v-model="values.type" :disabled="values.type === 1">
<el-option v-for="n in [1, 2]" :key="n" :disabled="n === 1" :label="$t(`group.type.${n}`)" :value="n"></el-option>
</el-select>
</el-form-item>
</template>
</dialog-form>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { queryGroup, createGroup, updateGroup, deleteGroup } from '@/api/user';
import DialogForm from '@/components/DialogForm.vue';
export default defineComponent({
components: { DialogForm },
props: { modelValue: { type: Boolean, required: true }, beanId: { required: true }, beanIds: { type: Array, required: true } },
emits: { 'update:modelValue': null, finished: null },
setup() {
const focus = ref<any>();
return { queryGroup, createGroup, updateGroup, deleteGroup, focus };
},
});
</script>

@ -1,158 +0,0 @@
<template>
<div>
<div class="mb-3">
<query-form :params="params"
@search="handleSearch"
@reset="handleReset">
<query-item :label="$t('group.name')"
name="Q_Contains_name"></query-item>
<query-item :label="$t('group.description')"
name="Q_Contains_description"></query-item>
</query-form>
</div>
<div>
<el-button type="primary"
:disabled="perm('group:create')"
:icon="Plus"
@click="handleAdd">{{ $t('add') }}</el-button>
<el-popconfirm :title="$t('confirmDelete')"
@confirm="handleDelete(selection.map((row) => row.id))">
<template #reference>
<el-button :disabled="selection.filter((row) => deletable(row.id)).length <= 0 || perm('group:delete')"
:icon="Delete">{{ $t('delete') }}</el-button>
</template>
</el-popconfirm>
<list-move class="ml-2"
:disabled="selection.length <= 0 || filtered || perm('org:update')"
@move="(type) => move(selection, type)" />
<column-setting name="group"
class="ml-2" />
</div>
<div class="block mt-3">
<el-table ref="table"
v-loading="loading"
:data="data"
@selection-change="(rows) => (selection = rows)"
@row-dblclick="(row) => handleEdit(row.id)"
@sort-change="handleSort">
<column-list name="group">
<el-table-column type="selection"
width="50"></el-table-column>
<el-table-column property="id"
label="ID"
width="64"
sortable="custom"></el-table-column>
<el-table-column property="name"
:label="$t('group.name')"
sortable="custom"
show-overflow-tooltip></el-table-column>
<el-table-column property="description"
:label="$t('group.description')"
min-width="150"
sortable="custom"
show-overflow-tooltip></el-table-column>
<el-table-column property="type"
:label="$t('group.type')"
sortable="custom"
show-overflow-tooltip
:formatter="(row) => $t(`group.type.${row.type}`)" />
<el-table-column :label="$t('table.action')">
<template #default="{ row }">
<el-button type="text"
:disabled="perm('group:update')"
@click="handleEdit(row.id)"
size="small">{{ $t('edit') }}</el-button>
<el-popconfirm :title="$t('confirmDelete')"
@confirm="handleDelete([row.id])">
<template #reference>
<el-button type="text"
:disabled="!deletable(row.id) || perm('group:delete')"
size="small">{{ $t('delete') }}</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</column-list>
</el-table>
</div>
<group-form v-model="formVisible"
:beanId="beanId"
:beanIds="beanIds"
@finished="fetchData" />
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { ElMessage } from 'element-plus';
import { Plus, Delete } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n';
import { perm } from '@/store/useCurrentUser';
import { moveList, toParams, resetParams } from '@/utils/common';
import { deleteGroup, queryGroupList, updateGroupOrder } from '@/api/user';
import { ColumnList, ColumnSetting } from '@/components/TableList';
import { QueryForm, QueryItem } from '@/components/QueryForm';
import ListMove from '@/components/ListMove.vue';
import GroupForm from './GroupForm.vue';
const { t } = useI18n();
const params = ref<any>({});
const sort = ref<any>();
const table = ref<any>();
const data = ref<any[]>([]);
const selection = ref<any[]>([]);
const loading = ref<boolean>(false);
const formVisible = ref<boolean>(false);
const beanId = ref<number>();
const beanIds = computed(() => data.value.map((row) => row.id));
const filtered = ref<boolean>(false);
const fetchData = async () => {
loading.value = true;
try {
data.value = await queryGroupList({ ...toParams(params.value), Q_OrderBy: sort.value });
filtered.value = Object.values(params.value).filter((v) => v !== undefined && v !== '').length > 0 || sort.value !== undefined;
} finally {
loading.value = false;
}
};
onMounted(fetchData);
const handleSort = ({ column, prop, order }: { column: any; prop: string; order: string }) => {
if (prop) {
sort.value = (column.sortBy ?? prop) + (order === 'descending' ? '_desc' : '');
} else {
sort.value = undefined;
}
fetchData();
};
const handleSearch = () => fetchData();
const handleReset = () => {
table.value.clearSort();
resetParams(params.value);
sort.value = undefined;
fetchData();
};
const handleAdd = () => {
beanId.value = undefined;
formVisible.value = true;
};
const handleEdit = (id: number) => {
beanId.value = id;
formVisible.value = true;
};
const deletable = (id: number) => id > 10;
const handleDelete = async (ids: number[]) => {
const deletableIds = ids.filter((id) => deletable(id));
if (deletableIds.length > 0) {
await deleteGroup(deletableIds);
fetchData();
ElMessage.success(t('success'));
}
};
const move = async (selected: any[], type: 'top' | 'up' | 'down' | 'bottom') => {
const list = moveList(selected, data.value, type);
await updateGroupOrder(list.map((item: any) => item.id));
};
</script>

@ -1,66 +0,0 @@
<template>
<dialog-form ref="form"
:name="$t('menu.user.role')"
:queryBean="queryRole"
:createBean="createRole"
:updateBean="updateRole"
:deleteBean="deleteRole"
:beanId="beanId"
:beanIds="beanIds"
:focus="focus"
:initValues="() => ({})"
:toValues="(bean) => ({ ...bean })"
:disableDelete="(bean) => bean.id <= 1"
perms="role"
:model-value="modelValue"
@update:model-value="$emit('update:modelValue', $event)"
@finished="$emit('finished')"
@beanChange="(bean) => tree?.setCheckedKeys(bean.permission?.split(',') ?? [])"
@beforeSubmit="
(values) =>
(values.permission = [...tree.getHalfCheckedNodes(), ...tree.getCheckedNodes()]
.filter((item) => item.perms)
.map((item) => item.perms?.join(','))
.join(','))
">
<template #default="{ values }">
<el-form-item prop="name"
:label="$t('role.name')"
:rules="{ required: true, message: () => $t('v.required') }">
<el-input v-model="values.name"
ref="focus"
maxlength="50"></el-input>
</el-form-item>
<el-form-item prop="description"
:label="$t('role.description')">
<el-input v-model="values.description"
maxlength="255"></el-input>
</el-form-item>
<el-form-item prop="permission"
:label="$t('role.permission')">
<el-tree ref="tree"
:data="perms"
node-key="key"
@check="form.setUnsaved(true)"
show-checkbox
default-expand-all
check-on-click-node />
</el-form-item>
</template>
</dialog-form>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { queryRole, createRole, updateRole, deleteRole } from '@/api/user';
import { getPermsTreeData } from '@/data';
import DialogForm from '@/components/DialogForm.vue';
defineProps({ modelValue: { type: Boolean, required: true }, beanId: { required: true }, beanIds: { type: Array, required: true } });
defineEmits({ 'update:modelValue': null, finished: null });
const focus = ref<any>();
const tree = ref<any>();
const form = ref<any>();
const perms = getPermsTreeData();
</script>

@ -1,117 +0,0 @@
<template>
<div>
<div class="mb-3">
<query-form :params="params" @search="handleSearch" @reset="handleReset">
<query-item :label="$t('role.name')" name="Q_Contains_name"></query-item>
<query-item :label="$t('role.description')" name="Q_Contains_description"></query-item>
</query-form>
</div>
<div>
<el-button type="primary" :icon="Plus" @click="handleAdd">{{ $t('add') }}</el-button>
<el-popconfirm :title="$t('confirmDelete')" @confirm="handleDelete(selection.map((row) => row.id))">
<template #reference>
<el-button :disabled="selection.length <= 0" :icon="Delete">{{ $t('delete') }}</el-button>
</template>
</el-popconfirm>
<list-move class="ml-2" :disabled="selection.length <= 0 || filtered || perm('role:update')" @move="(type) => move(selection, type)" />
<column-setting name="role" class="ml-2" />
</div>
<el-table
ref="table"
v-loading="loading"
:data="data"
@selection-change="(rows) => (selection = rows)"
@row-dblclick="(row) => handleEdit(row.id)"
@sort-change="handleSort"
class="mt-3 shadow bg-white"
>
<column-list name="role">
<el-table-column type="selection" width="50"></el-table-column>
<el-table-column property="id" label="ID" width="64" sortable="custom"></el-table-column>
<el-table-column property="name" :label="$t('role.name')" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column property="description" :label="$t('role.description')" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column :label="$t('table.action')">
<template #default="{ row }">
<el-button type="text" @click="handleEdit(row.id)" size="small">{{ $t('edit') }}</el-button>
<el-popconfirm :title="$t('confirmDelete')" @confirm="handleDelete([row.id])">
<template #reference>
<el-button type="text" size="small">{{ $t('delete') }}</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</column-list>
</el-table>
<role-form v-model="formVisible" :beanId="beanId" :beanIds="beanIds" @finished="fetchData" />
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { ElMessage } from 'element-plus';
import { Plus, Delete } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n';
import { perm } from '@/store/useCurrentUser';
import { deleteRole, queryRoleList, updateRoleOrder } from '@/api/user';
import { moveList, toParams, resetParams } from '@/utils/common';
import { ColumnList, ColumnSetting } from '@/components/TableList';
import { QueryForm, QueryItem } from '@/components/QueryForm';
import ListMove from '@/components/ListMove.vue';
import RoleForm from './RoleForm.vue';
const { t } = useI18n();
const params = ref<any>({});
const sort = ref<any>();
const table = ref<any>();
const data = ref<Array<any>>([]);
const selection = ref<Array<any>>([]);
const loading = ref<boolean>(false);
const formVisible = ref<boolean>(false);
const beanId = ref<number>();
const beanIds = computed(() => data.value.map((row) => row.id));
const filtered = ref<boolean>(false);
const fetchData = async () => {
loading.value = true;
try {
data.value = await queryRoleList({ ...toParams(params.value), Q_OrderBy: sort.value });
filtered.value = Object.values(params.value).filter((v) => v !== undefined && v !== '').length > 0 || sort.value !== undefined;
} finally {
loading.value = false;
}
};
onMounted(fetchData);
const handleSort = ({ column, prop, order }: { column: any; prop: string; order: string }) => {
if (prop) {
sort.value = (column.sortBy ?? prop) + (order === 'descending' ? '_desc' : '');
} else {
sort.value = undefined;
}
fetchData();
};
const handleSearch = () => fetchData();
const handleReset = () => {
table.value.clearSort();
resetParams(params.value);
sort.value = undefined;
fetchData();
};
const handleAdd = () => {
beanId.value = undefined;
formVisible.value = true;
};
const handleEdit = (id: number) => {
beanId.value = id;
formVisible.value = true;
};
const handleDelete = async (ids: number[]) => {
await deleteRole(ids);
fetchData();
ElMessage.success(t('success'));
};
const move = async (selected: any[], type: 'top' | 'up' | 'down' | 'bottom') => {
const list = moveList(selected, data.value, type);
await updateRoleOrder(list.map((item) => item.id));
};
</script>

@ -1,248 +0,0 @@
<template>
<dialog-form :name="$t('menu.user.user')"
:queryBean="queryUser"
:createBean="createUser"
:updateBean="updateUser"
:deleteBean="deleteUser"
:beanId="beanId"
:beanIds="beanIds"
:focus="focus"
:initValues="() => ({ gender: 'm', roleIds: [] })"
:toValues="(bean) => ({ ...bean, roleIds: bean.roleList.map((item:any) => item.id) })"
:disableDelete="(bean) => bean.id <= 1"
perms="user"
:model-value="modelValue"
@update:model-value="$emit('update:modelValue', $event)"
@finished="$emit('finished')"
large>
<template #default="{ values, bean, isEdit }">
<el-row>
<el-col :span="12">
<el-form-item prop="username"
:label="$t('user.username')"
:rules="[
{ required: true, message: () => $t('v.required') },
{
asyncValidator: async (rule, value, callback) => {
if (value !== bean.username && !(await usernameValidation(value))) {
callback($t('user.error.usernameExist'));
}
},
},
]">
<el-input v-model="values.username"
ref="focus"
maxlength="50"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="realName"
:label="$t('user.realName')">
<el-input v-model="values.realName"
maxlength="50"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="plainPassword"
:label="$t('user.plainPassword')"
:rules="[{ required: !isEdit, message: () => $t('v.required') }]">
<el-input v-model="values.plainPassword"
maxlength="50"
show-password></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="passwordAgain"
:label="$t('user.passwordAgain')"
:rules="[
{ required: !isEdit, message: () => $t('v.required') },
{
validator: (rule, value, callback) => {
if (value != values.plainPassword) {
callback($t('user.error.passwordNotMatch'));
} else {
callback();
}
},
trigger: 'blur',
},
]">
<el-input v-model="values.passwordAgain"
maxlength="50"
show-password></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="mobile"
:label="$t('user.mobile')"
:rules="[
{
asyncValidator: async (rule, value, callback) => {
if (value !== bean.mobile && !(await mobileValidation(value))) {
callback($t('user.error.mobileExist'));
}
},
},
]">
<el-input v-model="values.mobile"
maxlength="50"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="email"
:label="$t('user.email')"
:rules="[
{
asyncValidator: async (rule, value, callback) => {
if (value !== bean.email && !(await emailValidation(value))) {
callback($t('user.error.emailExist'));
}
},
},
]">
<el-input v-model="values.email"
maxlength="50"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="groupId"
:label="$t('user.group')"
:rules="{ required: true, message: () => $t('v.required') }">
<el-select v-model="values.groupId">
<el-option v-for="item in groupList"
:key="item.id"
:value="item.id"
:label="item.name"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="orgId"
:label="$t('user.org')"
:rules="{ required: true, message: () => $t('v.required') }">
<el-cascader v-model="values.orgId"
:options="orgList"
:props="{ value: 'id', label: 'name', checkStrictly: true }"
@change="(value) => (values.orgId = value[value.length - 1])"></el-cascader>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item prop="roleIds"
:label="$t('user.role')">
<el-checkbox-group v-model="values.roleIds">
<el-checkbox v-for="item in roleList"
:key="item.id"
:label="item.id">{{ item.name }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="rank"
:rules="[
{ required: true, message: () => $t('v.required') },
{ type: 'integer', message: () => $t('v.integer') },
]">
<template #label><label-tip message="user.rank" /></template>
<el-input v-model.number="values.rank"
maxlength="4"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="gender"
:label="$t('user.gender')"
:rules="{ required: true, message: () => $t('v.required') }">
<el-radio-group v-model="values.gender">
<el-radio :label="'m'">{{ $t('gender.male') }}</el-radio>
<el-radio :label="'f'">{{ $t('gender.female') }}</el-radio>
<el-radio :label="'n'">{{ $t('gender.none') }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="location"
:label="$t('user.location')">
<el-input v-model="values.location"
maxlength="255"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="birthday"
:label="$t('user.birthday')">
<el-date-picker v-model="values.birthday"
type="date"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item prop="bio"
:label="$t('user.bio')">
<el-input v-model="values.bio"
type="textarea"
:rows="3"
maxlength="2000"></el-input>
</el-form-item>
</el-col>
<el-col :span="12"
v-if="isEdit">
<el-form-item prop="created"
:label="$t('user.created')">
<el-date-picker v-model="values.created"
type="datetime"
disabled></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12"
v-if="isEdit">
<el-form-item prop="loginDate"
:label="$t('user.loginDate')">
<el-date-picker v-model="values.loginDate"
type="datetime"
disabled></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12"
v-if="isEdit">
<el-form-item prop="loginIp"
:label="$t('user.loginIp')">
<el-input v-model="values.loginIp"
disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="12"
v-if="isEdit">
<el-form-item prop="loginCount"
:label="$t('user.loginCount')">
<el-input v-model="values.loginCount"
disabled></el-input>
</el-form-item>
</el-col>
</el-row>
</template>
</dialog-form>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { queryUser, createUser, updateUser, deleteUser, usernameValidation, emailValidation, mobileValidation, queryGroupList, queryOrgList, queryRoleList } from '@/api/user';
import { toTree } from '@/utils/tree';
import DialogForm from '@/components/DialogForm.vue';
import LabelTip from '@/components/LabelTip.vue';
defineProps({ modelValue: { type: Boolean, required: true }, beanId: { required: true }, beanIds: { type: Array, required: true } });
defineEmits({ 'update:modelValue': null, finished: null });
const focus = ref<any>();
const groupList = ref<any[]>([]);
const orgList = ref<any[]>([]);
const roleList = ref<any[]>([]);
onMounted(() => {
queryGroupList({ Q_EQ_type: 2 }).then((result) => {
groupList.value = result;
});
queryOrgList().then((result) => {
orgList.value = toTree(result);
});
queryRoleList().then((result) => {
roleList.value = result;
});
});
</script>

@ -1,259 +0,0 @@
<template>
<div>
<div class="mb-3">
<query-form :params="params"
@search="handleSearch"
@reset="handleReset">
<query-item :label="$t('user.username')"
name="Q_Contains_username"></query-item>
<query-item :label="$t('user.mobile')"
name="Q_Contains_mobile"></query-item>
<query-item :label="$t('user.email')"
name="Q_Contains_email"></query-item>
<query-item :label="$t('user.rank')"
name="Q_GE_rank,Q_LE_rank"
type="number"></query-item>
<query-item :label="$t('user.created')"
name="Q_GE_@userExt-created_DateTime,Q_LE_@userExt-created_DateTime"
type="datetime"></query-item>
<query-item :label="$t('user.status')"
name="Q_In_status_Int"
:options="[0, 1].map((item) => ({ label: $t(`user.status.${item}`), value: item }))"></query-item>
</query-form>
</div>
<div>
<el-button type="primary"
:icon="Plus"
@click="handleAdd">{{ $t('add') }}</el-button>
<el-popconfirm :title="$t('confirmDelete')"
@confirm="handleDelete(selection.map((row) => row.id))">
<template #reference>
<el-button :disabled="selection.length <= 0 || perm('user:delete')"
:icon="Delete">{{ $t('delete') }}</el-button>
</template>
</el-popconfirm>
<column-setting name="user"
class="ml-2" />
</div>
<div class="block mt-3">
<el-table ref="table"
v-loading="loading"
:data="data"
@selection-change="(rows) => (selection = rows)"
@row-dblclick="(row) => handleEdit(row.id)"
@sort-change="handleSort">
<column-list name="user">
<el-table-column type="selection"
:selectable="deletable"
width="50"></el-table-column>
<el-table-column property="id"
label="ID"
width="64"
sortable="custom"></el-table-column>
<el-table-column property="username"
:label="$t('user.username')"
sortable="custom"
min-width="100"></el-table-column>
<el-table-column property="mobile"
:label="$t('user.mobile')"
sortable="custom"
display="none"
min-width="100"
show-overflow-tooltip></el-table-column>
<el-table-column property="email"
:label="$t('user.email')"
sortable="custom"
display="none"
min-width="100"
show-overflow-tooltip></el-table-column>
<el-table-column property="realName"
:label="$t('user.realName')"
sort-by="@userExt-realName"
sortable="custom"
min-width="100"
show-overflow-tooltip />
<el-table-column property="gender"
:label="$t('user.gender')"
sort-by="@userExt-gender"
sortable="custom"
display="none">
<template #default="{ row }">{{ $t(`gender.${row.gender}`) }}</template>
</el-table-column>
<el-table-column property="created"
:label="$t('user.created')"
sort-by="@userExt-created"
sortable="custom"
display="none"
width="170">
<template #default="{ row }">{{ dayjs(row.created).format('YYYY-MM-DD HH:mm:ss') }}</template>
</el-table-column>
<el-table-column property="birthday"
:label="$t('user.birthday')"
sort-by="@userExt-birthday"
sortable="custom"
display="none"
width="110">
<template #default="{ row }">{{ dayjs(row.birthday).format('YYYY-MM-DD') }}</template>
</el-table-column>
<el-table-column property="loginDate"
:label="$t('user.loginDate')"
sort-by="@userExt-loginDate"
sortable="custom"
display="none"
width="170">
<template #default="{ row }">{{ dayjs(row.loginDate).format('YYYY-MM-DD HH:mm:ss') }}</template>
</el-table-column>
<el-table-column property="loginIp"
:label="$t('user.loginIp')"
sort-by="@userExt-loginIp"
sortable="custom"
display="none"
show-overflow-tooltip />
<el-table-column property="loginCount"
:label="$t('user.loginCount')"
sort-by="@userExt-loginCount"
sortable="custom"
display="none"
show-overflow-tooltip />
<el-table-column property="org.name"
:label="$t('user.org')"
sort-by="org-name"
sortable="custom"
show-overflow-tooltip></el-table-column>
<el-table-column property="roles"
:label="$t('user.role')"
show-overflow-tooltip>
<template #default="{ row }">
<el-space>
<span v-for="item in row.roleList"
:key="item.id">{{ item.name }}</span>
</el-space>
</template>
</el-table-column>
<el-table-column property="group.name"
:label="$t('user.group')"
sort-by="group-name"
sortable="custom"
show-overflow-tooltip></el-table-column>
<el-table-column property="rank"
:label="$t('user.rank')"
sortable="custom"
show-overflow-tooltip></el-table-column>
<el-table-column property="status"
:label="$t('user.status')"
sortable="custom"
show-overflow-tooltip>
<template #default="{ row }">
<el-tag v-if="row.status === 0"
type="success"
size="small">{{ $t(`user.status.${row.status}`) }}</el-tag>
<el-tag v-if="row.status === 1"
type="danger"
size="small">{{ $t(`user.status.${row.status}`) }}</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('table.action')">
<template #default="{ row }">
<el-button type="text"
@click="handleEdit(row.id)"
:disabled="perm('user:show')"
size="small">{{ $t('edit') }}</el-button>
<el-popconfirm :title="$t('confirmDelete')"
@confirm="handleDelete([row.id])">
<template #reference>
<el-button type="text"
:disabled="!deletable(row) || perm('user:delete')"
size="small">{{ $t('delete') }}</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</column-list>
</el-table>
<el-pagination v-model:currentPage="currentPage"
v-model:pageSize="pageSize"
:total="total"
:page-sizes="pageSizes"
:layout="pageLayout"
@size-change="fetchData()"
@current-change="fetchData()"
small
background
class="px-3 py-2 justify-end"></el-pagination>
</div>
<user-form v-model="formVisible"
:beanId="beanId"
:beanIds="beanIds"
@finished="fetchData" />
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { ElMessage } from 'element-plus';
import { Plus, Delete } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n';
import dayjs from 'dayjs';
import { perm } from '@/store/useCurrentUser';
import { pageSizes, pageLayout, toParams, resetParams } from '@/utils/common';
import { deleteUser, queryUserPage } from '@/api/user';
import { ColumnList, ColumnSetting } from '@/components/TableList';
import { QueryForm, QueryItem } from '@/components/QueryForm';
import UserForm from './UserForm.vue';
const { t } = useI18n();
const params = ref<any>({});
const sort = ref<any>();
const currentPage = ref<number>(1);
const pageSize = ref<number>(10);
const total = ref<number>(0);
const table = ref<any>();
const data = ref<Array<any>>([]);
const selection = ref<Array<any>>([]);
const loading = ref<boolean>(false);
const formVisible = ref<boolean>(false);
const beanId = ref<number>();
const beanIds = computed(() => data.value.map((row) => row.id));
const fetchData = async () => {
loading.value = true;
try {
const { content, totalElements } = await queryUserPage({ ...toParams(params.value), Q_OrderBy: sort.value, page: currentPage.value, pageSize: pageSize.value });
data.value = content;
total.value = totalElements;
} finally {
loading.value = false;
}
};
onMounted(fetchData);
const handleSort = ({ column, prop, order }: { column: any; prop: string; order: string }) => {
if (prop) {
sort.value = (column.sortBy ?? prop) + (order === 'descending' ? '_desc' : '');
} else {
sort.value = undefined;
}
fetchData();
};
const handleSearch = () => fetchData();
const handleReset = () => {
table.value.clearSort();
resetParams(params.value);
sort.value = undefined;
fetchData();
};
const handleAdd = () => {
beanId.value = undefined;
formVisible.value = true;
};
const handleEdit = (id: number) => {
beanId.value = id;
formVisible.value = true;
};
const handleDelete = async (ids: number[]) => {
await deleteUser(ids);
fetchData();
ElMessage.success(t('success'));
};
const deletable = (bean: any) => bean.id > 1;
</script>
Loading…
Cancel
Save