feat: 添加数据反馈,数据导入功能
This commit is contained in:
parent
6e6bab05ac
commit
88ceb0f63b
@ -43,6 +43,8 @@ buttons:More: More
|
||||
buttons:Deselect: Deselect
|
||||
buttons:DeleteInBatches: Delete In Batches
|
||||
buttons:ExportInBatches: Export In Batches
|
||||
buttons:AgressInBatches: Agress In Batches
|
||||
buttons:DisagressInBatches: Disagress In Batches
|
||||
buttons:ExitInBatches: Exit In Batches
|
||||
buttons:ExportAll: Export All
|
||||
buttons:UploadAvatar: Upload Avatar
|
||||
@ -51,6 +53,8 @@ buttons:RoleAllocation: Role Allocation
|
||||
buttons:PermissionDetails: Permission Details
|
||||
buttons:ForceToExit: Force Exit
|
||||
buttons:DataAdmin: Data Admin
|
||||
buttons:Audit: Audit
|
||||
buttons:Feedback: Feedback
|
||||
search:Total: Total
|
||||
search:History: History
|
||||
search:Collect: Collect
|
||||
@ -117,8 +121,11 @@ menus:SystemConfig: System Config
|
||||
menus:CodeManager: HTS Code Mgnt
|
||||
menus:CodeQueryIndex: HTS Code Query
|
||||
menus:CodeQueryCount: Query Statistics
|
||||
menus:CodeQueryData: Data Maintenance
|
||||
menus:QueryCodedetails: Log Detail
|
||||
menus:DataQuality: Data Quality
|
||||
menus:DataImport: Data Import
|
||||
menus:DataFeedback: Data Feedback
|
||||
menus:DataMaintain: Data Export
|
||||
status:Load: Loading...
|
||||
status:Message: Message
|
||||
status:Notify: Notify
|
||||
|
@ -43,6 +43,8 @@ buttons:More: 更多
|
||||
buttons:Deselect: 取消选择
|
||||
buttons:DeleteInBatches: 批量删除
|
||||
buttons:ExportInBatches: 批量导出
|
||||
buttons:AgressInBatches: 批量通过
|
||||
buttons:DisagressInBatches: 批量驳回
|
||||
buttons:ExportAll: 全部导出
|
||||
buttons:UploadAvatar: 上传头像
|
||||
buttons:ResetPassword: 重置密码
|
||||
@ -51,6 +53,8 @@ buttons:PermissionDetails: 权限详情
|
||||
buttons:ForceToExit: 强制退出
|
||||
buttons:ExitInBatches: 批量强退
|
||||
buttons:DataAdmin: 数据管理
|
||||
buttons:Audit: 审核
|
||||
buttons:Feedback: 反馈
|
||||
search:Total: 共
|
||||
search:History: 搜索历史
|
||||
search:Collect: 收藏
|
||||
@ -117,8 +121,11 @@ menus:SystemConfig: 系统配置
|
||||
menus:CodeManager: 编码管理
|
||||
menus:CodeQueryIndex: 编码查询
|
||||
menus:CodeQueryCount: 查询统计
|
||||
menus:CodeQueryData: 数据维护
|
||||
menus:QueryCodedetails: 日志详情
|
||||
menus:DataQuality: 数据质量
|
||||
menus:DataImport: 数据导入
|
||||
menus:DataFeedback: 数据反馈
|
||||
menus:DataMaintain: 数据维护
|
||||
status:Load: 加载中...
|
||||
status:Message: 消息
|
||||
status:Notify: 通知
|
||||
|
172
src/api/code.ts
172
src/api/code.ts
@ -1,5 +1,11 @@
|
||||
import { http } from "@/utils/http";
|
||||
import type { CodeInfo, QueryCodeLogInfo, QueryCodeResult } from "types/code";
|
||||
import type {
|
||||
CodeFeedbackInfo,
|
||||
CodeImportInfo,
|
||||
CodeInfo,
|
||||
QueryCodeLogInfo,
|
||||
QueryCodeResult
|
||||
} from "types/code";
|
||||
import { filterEmptyObject } from "./utils";
|
||||
|
||||
/**
|
||||
@ -77,9 +83,19 @@ interface GetCodeListParams {
|
||||
/** 每页条数 */
|
||||
pageSize: number;
|
||||
/** 编码 */
|
||||
code: string;
|
||||
code?: string;
|
||||
/** 编码描述 */
|
||||
description: string;
|
||||
description?: string;
|
||||
/**用户账号 */
|
||||
username?: string;
|
||||
/**用户昵称 */
|
||||
nickname?: string;
|
||||
/**部门ID */
|
||||
department_id?: string;
|
||||
/**开始时间 */
|
||||
startTime?: string | number;
|
||||
/**结束时间 */
|
||||
endTime?: string | number;
|
||||
}
|
||||
/**
|
||||
* 获取编码列表
|
||||
@ -160,3 +176,153 @@ export const getCodeLogListAllAPI = (params: {
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**删除编码导入 */
|
||||
export const deleteCodeImportAPI = (id: string) => {
|
||||
return http.request<null>("delete", `/api/code/deleteCodeImport/${id}`);
|
||||
};
|
||||
|
||||
/**批量删除编码导入 */
|
||||
export const deleteCodeImportListAPI = (data: { ids: string[] }) => {
|
||||
return http.request<null>("post", `/api/code/deleteCodeImportList`, { data });
|
||||
};
|
||||
|
||||
/**编码导入审核 */
|
||||
export const putCodeImportAuditAPI = (data: {
|
||||
/**状态 */
|
||||
status: number;
|
||||
/**编码ID列表 */
|
||||
ids: string[];
|
||||
}) => {
|
||||
return http.request<null>("put", `/api/code/codeImportAudit`, { data });
|
||||
};
|
||||
|
||||
/**获取编码导入列表参数 */
|
||||
interface GetCodeImportListParams {
|
||||
/** 当前页码 */
|
||||
page: number;
|
||||
/** 每页条数 */
|
||||
pageSize: number;
|
||||
/** 状态 */
|
||||
status?: number | string;
|
||||
/**编码 */
|
||||
code?: string;
|
||||
/**编码描述 */
|
||||
description?: string;
|
||||
/**用户账号 */
|
||||
username?: string;
|
||||
/**用户昵称 */
|
||||
nickname?: string;
|
||||
/**部门ID */
|
||||
department_id?: string;
|
||||
/**开始时间 */
|
||||
startTime?: string | number;
|
||||
/**结束时间 */
|
||||
endTime?: string | number;
|
||||
}
|
||||
/**
|
||||
* 获取编码导入列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export const getCodeImportListAPI = (params: GetCodeImportListParams) => {
|
||||
return http.request<QueryListResult<CodeImportInfo>>(
|
||||
"get",
|
||||
`/api/code/codeImportList`,
|
||||
{
|
||||
params: filterEmptyObject(params)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**修改编码导入 */
|
||||
export const putUpdateCodeImportAPI = (data: AddCodeParams, id: string) => {
|
||||
return http.request<null>("put", `/api/code/updateCodeImport/${id}`, {
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**添加反馈参数 */
|
||||
interface AddCodeFeedbackParams {
|
||||
/**反馈编码 */
|
||||
feedback_code: string;
|
||||
/**反馈文本 */
|
||||
feedback_description: string;
|
||||
/**编码ID */
|
||||
code_id: string;
|
||||
}
|
||||
|
||||
/**添加反馈 */
|
||||
export const postAddCodeFeedbackAPI = (data: AddCodeFeedbackParams) => {
|
||||
return http.request<null>("post", `/api/code/addFeedback`, { data });
|
||||
};
|
||||
|
||||
/**删除反馈 */
|
||||
export const deleteCodeFeedbackAPI = (id: string) => {
|
||||
return http.request<null>("delete", `/api/code/deleteFeedback/${id}`);
|
||||
};
|
||||
/**批量删除反馈 */
|
||||
export const deleteCodeFeedbackListAPI = (data: { ids: string[] }) => {
|
||||
return http.request<null>("post", `/api/code/deleteFeedbackList`, { data });
|
||||
};
|
||||
|
||||
/**修改编码反馈 */
|
||||
export const putUpdateCodeFeedbackAPI = (
|
||||
data: AddCodeFeedbackParams,
|
||||
id: string
|
||||
) => {
|
||||
return http.request<null>("put", `/api/code/updateFeedback/${id}`, {
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**获取编码反馈列表参数 */
|
||||
interface GetCodeFeedbackListParams {
|
||||
/** 当前页码 */
|
||||
page: number;
|
||||
/** 每页条数 */
|
||||
pageSize: number;
|
||||
/** 状态 */
|
||||
status?: number | string;
|
||||
/**编码 */
|
||||
code?: string;
|
||||
/**反馈编码 */
|
||||
feedback_code?: string;
|
||||
/**反馈文本 */
|
||||
feedback_description?: string;
|
||||
/**用户账号 */
|
||||
username?: string;
|
||||
/**用户昵称 */
|
||||
nickname?: string;
|
||||
/**部门ID */
|
||||
department_id?: string;
|
||||
/**开始时间 */
|
||||
startTime?: string | number;
|
||||
/**结束时间 */
|
||||
endTime?: string | number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取编码反馈列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export const getCodeFeedbackListAPI = (params: GetCodeFeedbackListParams) => {
|
||||
return http.request<QueryListResult<CodeFeedbackInfo>>(
|
||||
"get",
|
||||
`/api/code/feedbackList`,
|
||||
{
|
||||
params: filterEmptyObject(params)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**反馈审核 */
|
||||
export const putCodeFeedbackAuditAPI = (data: {
|
||||
/**状态 */
|
||||
status: number;
|
||||
/**反馈ID列表 */
|
||||
ids: string[];
|
||||
}) => {
|
||||
return http.request<null>("put", `/api/code/feedbackAudit`, { data });
|
||||
};
|
||||
|
107
src/views/codes/index/components/form.vue
Normal file
107
src/views/codes/index/components/form.vue
Normal file
@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
:model="newFormInline"
|
||||
:rules="formRules"
|
||||
label-width="82px"
|
||||
>
|
||||
<el-row :gutter="30">
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="编码ID" prop="code_id">
|
||||
<el-input
|
||||
v-model="newFormInline.code_id"
|
||||
placeholder="请输入编码ID~"
|
||||
clearable
|
||||
disabled
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="当前编码" prop="code">
|
||||
<el-input
|
||||
v-model="newFormInline.code"
|
||||
placeholder="请输入当前编码~"
|
||||
clearable
|
||||
disabled
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="当前描述" prop="description">
|
||||
<el-input
|
||||
v-model="newFormInline.description"
|
||||
placeholder="请输入当前编码描述~"
|
||||
clearable
|
||||
disabled
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="正确编码" prop="feedback_code">
|
||||
<el-input
|
||||
v-model="newFormInline.feedback_code"
|
||||
placeholder="请输入正确的编码描述~"
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="正确描述" prop="feedback_description">
|
||||
<el-input
|
||||
v-model="newFormInline.feedback_description"
|
||||
placeholder="请输入正确的编码描述~"
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import ReCol from "@/components/ReCol";
|
||||
import type { FormRules } from "element-plus";
|
||||
const ruleFormRef = ref();
|
||||
interface PropsInfo {
|
||||
/**编码ID */
|
||||
code_id: string;
|
||||
/**编码 */
|
||||
code: string;
|
||||
/**编码描述 */
|
||||
description: string;
|
||||
/**反馈编码 */
|
||||
feedback_code: string;
|
||||
/**反馈文本 */
|
||||
feedback_description: string;
|
||||
}
|
||||
|
||||
type ProsData = {
|
||||
formInline: PropsInfo;
|
||||
};
|
||||
/** 自定义表单规则校验 */
|
||||
const formRules = reactive<FormRules>({
|
||||
feedback_code: [
|
||||
{ required: true, message: "反馈编码为必填项", trigger: "blur" }
|
||||
],
|
||||
feedback_description: [
|
||||
{ required: true, message: "反馈描述为必填项", trigger: "blur" }
|
||||
]
|
||||
});
|
||||
const props = withDefaults(defineProps<ProsData>(), {
|
||||
formInline: () => ({
|
||||
code_id: "",
|
||||
code: "",
|
||||
description: "",
|
||||
feedback_code: "",
|
||||
feedback_description: ""
|
||||
})
|
||||
});
|
||||
const newFormInline = ref<PropsInfo>(props.formInline);
|
||||
defineExpose({ newFormInline });
|
||||
</script>
|
@ -210,6 +210,14 @@
|
||||
item.match_rate ? `${item.match_rate}%` : "0%"
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-button
|
||||
v-if="hasAuth('code:btn:addFeedback')"
|
||||
class="w-full top-2"
|
||||
type="primary"
|
||||
:disabled="!hasAuth('code:btn:addFeedback')"
|
||||
@click="handleFeedback(item)"
|
||||
>{{ t("buttons:Feedback") }}</el-button
|
||||
>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-drawer>
|
||||
@ -262,7 +270,8 @@ const {
|
||||
onDownloadTemplate,
|
||||
handleDetail,
|
||||
exportToExcel,
|
||||
onbatchExport
|
||||
onbatchExport,
|
||||
handleFeedback
|
||||
} = useIndex(tableRef);
|
||||
</script>
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { message } from "@/utils/message";
|
||||
import { type Ref, ref, reactive } from "vue";
|
||||
import editForm from "../components/form.vue";
|
||||
import { type Ref, ref, reactive, h } from "vue";
|
||||
import * as XLSX from "xlsx";
|
||||
import type { PaginationProps } from "@pureadmin/table";
|
||||
import type { QueryCodeResult, QueryResult, QueryResultItem } from "types/code";
|
||||
@ -11,10 +12,12 @@ import {
|
||||
import {
|
||||
getQueryCodeAPI,
|
||||
getQueryTemplateAPI,
|
||||
postAddCodeFeedbackAPI,
|
||||
postCodeInfoAPI
|
||||
} from "@/api/code";
|
||||
import { deleteFileAPI, postUploadFileAPI } from "@/api/file";
|
||||
import { getKeyList, cloneDeep } from "@pureadmin/utils";
|
||||
import { addDialog } from "@/components/ReDialog";
|
||||
|
||||
export const useIndex = (tableRef: Ref) => {
|
||||
/**
|
||||
@ -26,7 +29,7 @@ export const useIndex = (tableRef: Ref) => {
|
||||
/**
|
||||
* 表单Ref
|
||||
*/
|
||||
// const formRef = ref(null);
|
||||
const formRef = ref(null);
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
@ -371,6 +374,50 @@ export const useIndex = (tableRef: Ref) => {
|
||||
|
||||
exportToExcel([exportData], "查询结果");
|
||||
};
|
||||
/**处理反馈 */
|
||||
const handleFeedback = async (row: QueryResultItem) => {
|
||||
addDialog({
|
||||
title: `反馈错误`,
|
||||
props: {
|
||||
formInline: {
|
||||
code_id: row?.id ?? "",
|
||||
code: row?.code ?? "",
|
||||
description: row?.description ?? "",
|
||||
feedback_code: row?.code ?? "",
|
||||
feedback_description: row?.description ?? ""
|
||||
}
|
||||
},
|
||||
width: "45%",
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () =>
|
||||
h(editForm, {
|
||||
formInline: {
|
||||
code_id: row?.id ?? "",
|
||||
code: row?.code ?? "",
|
||||
description: row?.description ?? "",
|
||||
feedback_code: row?.code ?? "",
|
||||
feedback_description: row?.description ?? ""
|
||||
},
|
||||
ref: formRef
|
||||
}),
|
||||
beforeSure: async (done, {}) => {
|
||||
const FormData = formRef.value.newFormInline;
|
||||
const res = await postAddCodeFeedbackAPI({
|
||||
code_id: row.id,
|
||||
feedback_description: FormData.feedback_description,
|
||||
feedback_code: FormData.feedback_code
|
||||
});
|
||||
if (res.success) {
|
||||
message("反馈成功!", { type: "success" });
|
||||
done();
|
||||
} else {
|
||||
message("反馈失败!", { type: "error" });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
return {
|
||||
form,
|
||||
dataList,
|
||||
@ -396,6 +443,7 @@ export const useIndex = (tableRef: Ref) => {
|
||||
onDownloadTemplate,
|
||||
handleDetail,
|
||||
exportToExcel,
|
||||
onbatchExport
|
||||
onbatchExport,
|
||||
handleFeedback
|
||||
};
|
||||
};
|
||||
|
@ -135,6 +135,14 @@
|
||||
item.match_rate ? `${item.match_rate}%` : "0%"
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-button
|
||||
v-if="hasAuth('code:btn:addFeedback')"
|
||||
class="w-full top-2"
|
||||
type="primary"
|
||||
:disabled="!hasAuth('code:btn:addFeedback')"
|
||||
@click="handleFeedback(item)"
|
||||
>{{ t("buttons:Feedback") }}</el-button
|
||||
>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-drawer>
|
||||
@ -145,6 +153,7 @@
|
||||
defineOptions({
|
||||
name: "QueryCodedetails"
|
||||
});
|
||||
import editForm from "./form.vue";
|
||||
import { ref, reactive, onMounted, h } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import dayjs from "dayjs";
|
||||
@ -160,15 +169,15 @@ import type {
|
||||
QueryResult,
|
||||
QueryResultItem
|
||||
} from "types/code";
|
||||
import { getCodeLogInfoAPI } from "@/api/code";
|
||||
import { getCodeLogInfoAPI, postAddCodeFeedbackAPI } from "@/api/code";
|
||||
import { PaginationProps } from "@pureadmin/table";
|
||||
import { message } from "@/utils/message";
|
||||
import { hasAuth } from "@/utils/auth";
|
||||
import { addDialog } from "@/components/ReDialog";
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const getParameter = isEmpty(route.params) ? route.query : route.params;
|
||||
console.log(getParameter);
|
||||
// /**初始化加载页面 */
|
||||
// function init() {
|
||||
// Object.keys(getParameter).forEach(param => {
|
||||
@ -203,6 +212,7 @@ const queryInfo = ref<QueryCodeLogInfo>();
|
||||
*/
|
||||
const dataList = ref<QueryResult[]>([]);
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
/**抽屉状态 */
|
||||
const drawerStatus = ref<boolean>(false);
|
||||
const loading = ref(true);
|
||||
@ -403,6 +413,50 @@ const onbatchExport = async () => {
|
||||
|
||||
exportToExcel([exportData], "查询结果");
|
||||
};
|
||||
/**处理反馈 */
|
||||
const handleFeedback = async (row: QueryResultItem) => {
|
||||
addDialog({
|
||||
title: `反馈错误`,
|
||||
props: {
|
||||
formInline: {
|
||||
code_id: row?.id ?? "",
|
||||
code: row?.code ?? "",
|
||||
description: row?.description ?? "",
|
||||
feedback_code: row?.code ?? "",
|
||||
feedback_description: row?.description ?? ""
|
||||
}
|
||||
},
|
||||
width: "45%",
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () =>
|
||||
h(editForm, {
|
||||
formInline: {
|
||||
code_id: row?.id ?? "",
|
||||
code: row?.code ?? "",
|
||||
description: row?.description ?? "",
|
||||
feedback_code: row?.code ?? "",
|
||||
feedback_description: row?.description ?? ""
|
||||
},
|
||||
ref: formRef
|
||||
}),
|
||||
beforeSure: async (done, {}) => {
|
||||
const FormData = formRef.value.newFormInline;
|
||||
const res = await postAddCodeFeedbackAPI({
|
||||
code_id: row.id,
|
||||
feedback_description: FormData.feedback_description,
|
||||
feedback_code: FormData.feedback_code
|
||||
});
|
||||
if (res.success) {
|
||||
message("反馈成功!", { type: "success" });
|
||||
done();
|
||||
} else {
|
||||
message("反馈失败!", { type: "error" });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
onMounted(async () => {
|
||||
await getQueryInfo();
|
||||
});
|
||||
|
107
src/views/codes/log/components/form.vue
Normal file
107
src/views/codes/log/components/form.vue
Normal file
@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
:model="newFormInline"
|
||||
:rules="formRules"
|
||||
label-width="82px"
|
||||
>
|
||||
<el-row :gutter="30">
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="编码ID" prop="code_id">
|
||||
<el-input
|
||||
v-model="newFormInline.code_id"
|
||||
placeholder="请输入编码ID~"
|
||||
clearable
|
||||
disabled
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="反馈编码" prop="code">
|
||||
<el-input
|
||||
v-model="newFormInline.code"
|
||||
placeholder="请输入反馈编码~"
|
||||
clearable
|
||||
disabled
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="编码描述" prop="description">
|
||||
<el-input
|
||||
v-model="newFormInline.description"
|
||||
placeholder="请输入编码描述~"
|
||||
clearable
|
||||
disabled
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="正确编码" prop="feedback_code">
|
||||
<el-input
|
||||
v-model="newFormInline.feedback_code"
|
||||
placeholder="请输入正确的编码~"
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="正确描述" prop="feedback_description">
|
||||
<el-input
|
||||
v-model="newFormInline.feedback_description"
|
||||
placeholder="请输入正确的编码描述~"
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import ReCol from "@/components/ReCol";
|
||||
import type { FormRules } from "element-plus";
|
||||
const ruleFormRef = ref();
|
||||
interface PropsInfo {
|
||||
/**编码ID */
|
||||
code_id: string;
|
||||
/**编码 */
|
||||
code: string;
|
||||
/**编码描述 */
|
||||
description: string;
|
||||
/**反馈编码 */
|
||||
feedback_code: string;
|
||||
/**反馈文本 */
|
||||
feedback_description: string;
|
||||
}
|
||||
|
||||
type ProsData = {
|
||||
formInline: PropsInfo;
|
||||
};
|
||||
/** 自定义表单规则校验 */
|
||||
const formRules = reactive<FormRules>({
|
||||
feedback_code: [
|
||||
{ required: true, message: "反馈编码为必填项", trigger: "blur" }
|
||||
],
|
||||
feedback_description: [
|
||||
{ required: true, message: "反馈内容为必填项", trigger: "blur" }
|
||||
]
|
||||
});
|
||||
const props = withDefaults(defineProps<ProsData>(), {
|
||||
formInline: () => ({
|
||||
code_id: "",
|
||||
code: "",
|
||||
description: "",
|
||||
feedback_code: "",
|
||||
feedback_description: ""
|
||||
})
|
||||
});
|
||||
const newFormInline = ref<PropsInfo>(props.formInline);
|
||||
defineExpose({ newFormInline });
|
||||
</script>
|
225
src/views/data/feedback/components/form.vue
Normal file
225
src/views/data/feedback/components/form.vue
Normal file
@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
:model="newFormInline"
|
||||
:rules="formRules"
|
||||
label-width="82px"
|
||||
>
|
||||
<el-row :gutter="30">
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="编码ID" prop="code_id">
|
||||
<el-input
|
||||
v-model="newFormInline.code_id"
|
||||
placeholder="请输入编码ID~"
|
||||
clearable
|
||||
disabled
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="反馈编码" prop="code">
|
||||
<el-input
|
||||
v-model="newFormInline.code"
|
||||
placeholder="请输入反馈编码~"
|
||||
clearable
|
||||
disabled
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="编码描述" prop="description">
|
||||
<el-input
|
||||
v-model="newFormInline.description"
|
||||
placeholder="请输入编码描述~"
|
||||
clearable
|
||||
disabled
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="反馈编码" prop="feedback_code">
|
||||
<el-input
|
||||
v-model="newFormInline.feedback_code"
|
||||
placeholder="请输入反馈编码~"
|
||||
clearable
|
||||
:disabled="newFormInline.way === '审核'"
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="反馈描述" prop="feedback_description">
|
||||
<el-input
|
||||
v-model="newFormInline.feedback_description"
|
||||
placeholder="请输入反馈编码描述~"
|
||||
clearable
|
||||
:disabled="newFormInline.way === '审核'"
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="用户ID" prop="user_id">
|
||||
<el-input
|
||||
v-model="newFormInline.user_id"
|
||||
placeholder="请输入用户ID~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="用户账号" prop="username">
|
||||
<el-input
|
||||
v-model="newFormInline.username"
|
||||
placeholder="请输入用户账号~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="用户名称" prop="nickname">
|
||||
<el-input
|
||||
v-model="newFormInline.nickname"
|
||||
placeholder="请输入用户名称~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="所属部门" prop="department_name">
|
||||
<el-input
|
||||
v-model="newFormInline.department_name"
|
||||
placeholder="请输入所属部门~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="创建时间" prop="create_time">
|
||||
<el-input
|
||||
:value="
|
||||
dayjs(newFormInline.create_time).format('YYYY-MM-DD HH:mm:ss')
|
||||
"
|
||||
placeholder="请输入创建时间~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="修改时间" prop="update_time">
|
||||
<el-input
|
||||
:value="
|
||||
dayjs(newFormInline.update_time).format('YYYY-MM-DD HH:mm:ss')
|
||||
"
|
||||
placeholder="请输入修改时间~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="审核状态" prop="status">
|
||||
<el-select
|
||||
v-model="newFormInline.status"
|
||||
placeholder="请选择状态~"
|
||||
clearable
|
||||
disabled
|
||||
class="w-[full]"
|
||||
>
|
||||
<el-option label="审核通过" :value="1" />
|
||||
<el-option label="审核未通过" :value="2" />
|
||||
<el-option label="待审核" :value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import dayjs from "dayjs";
|
||||
import { ref, reactive } from "vue";
|
||||
import ReCol from "@/components/ReCol";
|
||||
import type { FormRules } from "element-plus";
|
||||
const ruleFormRef = ref();
|
||||
interface PropsInfo {
|
||||
/**方式 */
|
||||
way: string;
|
||||
/**反馈ID */
|
||||
id: string;
|
||||
/**编码ID */
|
||||
code_id: string;
|
||||
/**编码 */
|
||||
code: string;
|
||||
/**编码描述 */
|
||||
description: string;
|
||||
/**反馈编码 */
|
||||
feedback_code: string;
|
||||
/**反馈文本 */
|
||||
feedback_description: string;
|
||||
/** 创建时间 */
|
||||
create_time: string;
|
||||
/** 更新时间 */
|
||||
update_time: string;
|
||||
/**用户ID */
|
||||
user_id: string;
|
||||
/**用户昵称 */
|
||||
nickname: string;
|
||||
/**用户账号 */
|
||||
username: string;
|
||||
/**部门ID */
|
||||
department_id: string;
|
||||
/**部门名称 */
|
||||
department_name: string;
|
||||
/**审核状态 */
|
||||
status: number;
|
||||
}
|
||||
|
||||
type ProsData = {
|
||||
formInline: PropsInfo;
|
||||
};
|
||||
/** 自定义表单规则校验 */
|
||||
const formRules = reactive<FormRules>({
|
||||
feedback_code: [
|
||||
{ required: true, message: "反馈编码为必填项", trigger: "blur" }
|
||||
],
|
||||
feedback_description: [
|
||||
{ required: true, message: "反馈内容为必填项", trigger: "blur" }
|
||||
]
|
||||
});
|
||||
const props = withDefaults(defineProps<ProsData>(), {
|
||||
formInline: () => ({
|
||||
id: "",
|
||||
way: "新增",
|
||||
code_id: "",
|
||||
code: "",
|
||||
description: "",
|
||||
feedback_code: "",
|
||||
feedback_description: "",
|
||||
status: 0,
|
||||
create_time: "",
|
||||
update_time: "",
|
||||
user_id: "",
|
||||
nickname: "",
|
||||
username: "",
|
||||
department_id: "",
|
||||
department_name: ""
|
||||
})
|
||||
});
|
||||
const newFormInline = ref<PropsInfo>(props.formInline);
|
||||
defineExpose({ newFormInline });
|
||||
</script>
|
298
src/views/data/feedback/index.vue
Normal file
298
src/views/data/feedback/index.vue
Normal file
@ -0,0 +1,298 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:inline="true"
|
||||
:model="form"
|
||||
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]"
|
||||
>
|
||||
<el-form-item label="用户账号" prop="usename">
|
||||
<el-input
|
||||
v-model="form.username"
|
||||
placeholder="请输入用户账号~"
|
||||
clearable
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名称" prop="nickname">
|
||||
<el-input
|
||||
v-model="form.nickname"
|
||||
placeholder="请输入用户昵称~"
|
||||
clearable
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="反馈编码" prop="code">
|
||||
<el-input
|
||||
v-model="form.code"
|
||||
placeholder="请输入反馈编码~"
|
||||
clearable
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="反馈内容" prop="feedback">
|
||||
<el-input
|
||||
v-model="form.feedback"
|
||||
clearable
|
||||
placeholder="请输入反馈内容~"
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="hasAuth('code:data:feedbackAdmin')"
|
||||
label="所属部门:"
|
||||
prop="department_id"
|
||||
>
|
||||
<el-cascader
|
||||
v-model="form.department_id"
|
||||
class="!w-[200px]"
|
||||
:options="departments"
|
||||
:props="{
|
||||
value: 'id',
|
||||
label: 'name',
|
||||
emitPath: false,
|
||||
checkStrictly: true
|
||||
}"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择所属部门~"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span>{{ data.name }}</span>
|
||||
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
||||
</template>
|
||||
</el-cascader>
|
||||
</el-form-item>
|
||||
<el-form-item label="反馈时间" prop="timeRange">
|
||||
<el-date-picker
|
||||
v-model="form.timeRange"
|
||||
:shortcuts="getPickerShortcuts()"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期时间"
|
||||
end-placeholder="结束日期时间"
|
||||
value-format="x"
|
||||
unlink-panels
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="useRenderIcon('ri:search-line')"
|
||||
:loading="loading"
|
||||
@click="onSearch"
|
||||
>
|
||||
{{ t("buttons:Search") }}
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
|
||||
{{ t("buttons:Reset") }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<PureTableBar title="数据反馈" :columns="columns" @refresh="onSearch">
|
||||
<template v-slot="{ size, dynamicColumns }">
|
||||
<div
|
||||
v-if="selectedNum > 0"
|
||||
v-motion-fade
|
||||
class="bg-[var(--el-fill-color-light)] w-full h-[46px] mb-2 pl-4 flex items-center"
|
||||
>
|
||||
<div class="flex-auto">
|
||||
<span
|
||||
style="font-size: var(--el-font-size-base)"
|
||||
class="text-[rgba(42,46,54,0.5)] dark:text-[rgba(220,220,242,0.5)]"
|
||||
>
|
||||
已选 {{ selectedNum }} 项
|
||||
</span>
|
||||
<el-button type="primary" text @click="onSelectionCancel">
|
||||
{{ t("buttons:Deselect") }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-popconfirm
|
||||
v-if="hasAuth('code:btn:feedbackAudit')"
|
||||
title="是否确认通过审核?"
|
||||
@confirm="onbatchAgree"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
type="success"
|
||||
text
|
||||
class="mr-1"
|
||||
:disabled="
|
||||
selectedNum < 0 || !hasAuth('code:btn:feedbackAudit')
|
||||
"
|
||||
>
|
||||
{{ t("buttons:AgressInBatches") }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-popconfirm
|
||||
v-if="hasAuth('code:btn:feedbackAudit')"
|
||||
title="是否确认驳回?"
|
||||
@confirm="onbatchDisagree"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
type="danger"
|
||||
text
|
||||
class="mr-1"
|
||||
:disabled="
|
||||
selectedNum < 0 || !hasAuth('code:btn:feedbackAudit')
|
||||
"
|
||||
>
|
||||
{{ t("buttons:DisagressInBatches") }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-popconfirm
|
||||
v-if="hasAuth('code:btn:deleteFeedback')"
|
||||
title="是否确认删除?"
|
||||
@confirm="onbatchDel"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
type="danger"
|
||||
text
|
||||
class="mr-1"
|
||||
:disabled="
|
||||
selectedNum < 0 || !hasAuth('code:btn:deleteFeedback')
|
||||
"
|
||||
>
|
||||
{{ t("buttons:DeleteInBatches") }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</div>
|
||||
<pure-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
adaptive
|
||||
border
|
||||
stripe
|
||||
:adaptiveConfig="{ offsetBottom: 45 }"
|
||||
align-whole="center"
|
||||
table-layout="auto"
|
||||
:loading="loading"
|
||||
:size="size"
|
||||
:data="dataList"
|
||||
:columns="dynamicColumns"
|
||||
:pagination="pagination"
|
||||
:paginationSmall="size === 'small' ? true : false"
|
||||
:header-cell-style="{
|
||||
background: 'var(--el-fill-color-light)',
|
||||
color: 'var(--el-text-color-primary)'
|
||||
}"
|
||||
@selection-change="handleSelectionChange"
|
||||
@page-size-change="handleSizeChange"
|
||||
@page-current-change="handleCurrentChange"
|
||||
>
|
||||
<template #operation="{ row }">
|
||||
<el-button
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
:size="size"
|
||||
:disabled="!hasAuth('code:btn:updateFeedback')"
|
||||
:icon="useRenderIcon(EditPen)"
|
||||
@click="openDialog('修改', row)"
|
||||
>
|
||||
{{ t("buttons:Update") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="reset-margin"
|
||||
link
|
||||
type="warning"
|
||||
:size="size"
|
||||
:disabled="!hasAuth('code:btn:feedbackAudit')"
|
||||
:icon="useRenderIcon(Read)"
|
||||
@click="handleAudit(row)"
|
||||
>
|
||||
{{ t("buttons:Audit") }}
|
||||
</el-button>
|
||||
<el-popconfirm
|
||||
:title="`是否确认删除编码名为 ${row.code} 的这条数据`"
|
||||
@confirm="handleDelete(row)"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
class="reset-margin"
|
||||
link
|
||||
type="danger"
|
||||
:size="size"
|
||||
:disabled="!hasAuth('code:btn:deleteFeedback')"
|
||||
:icon="useRenderIcon(Delete)"
|
||||
>
|
||||
{{ t("buttons:Delete") }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</pure-table>
|
||||
</template>
|
||||
</PureTableBar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: "DataFeedBack"
|
||||
});
|
||||
import { ref } from "vue";
|
||||
import { useCode } from "./utils/hook";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { getPickerShortcuts } from "@/views/monitor/utils";
|
||||
import { PureTableBar } from "@/components/RePureTableBar";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import Delete from "@iconify-icons/ep/delete";
|
||||
import EditPen from "@iconify-icons/ep/edit-pen";
|
||||
import Refresh from "@iconify-icons/ep/refresh";
|
||||
import Read from "@iconify-icons/ep/place";
|
||||
import { hasAuth } from "@/utils/auth";
|
||||
const { t } = useI18n();
|
||||
|
||||
/**
|
||||
* 表格Ref
|
||||
*/
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
const {
|
||||
form,
|
||||
dataList,
|
||||
loading,
|
||||
pagination,
|
||||
columns,
|
||||
selectedNum,
|
||||
departments,
|
||||
openDialog,
|
||||
onSearch,
|
||||
resetForm,
|
||||
handleDelete,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
handleSelectionChange,
|
||||
onSelectionCancel,
|
||||
onbatchDel,
|
||||
handleAudit,
|
||||
onbatchDisagree,
|
||||
onbatchAgree
|
||||
} = useCode(tableRef);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.el-dropdown-menu__item i) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:deep(.el-button:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin: 24px 24px 0 !important;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
551
src/views/data/feedback/utils/hook.tsx
Normal file
551
src/views/data/feedback/utils/hook.tsx
Normal file
@ -0,0 +1,551 @@
|
||||
import dayjs from "dayjs";
|
||||
import editForm from "../components/form.vue";
|
||||
import { message } from "@/utils/message";
|
||||
import { type Ref, ref, reactive, onMounted, h } from "vue";
|
||||
import { addDialog, closeDialog } from "@/components/ReDialog";
|
||||
import type { PaginationProps } from "@pureadmin/table";
|
||||
import type { CodeFeedbackInfo } from "types/code";
|
||||
import {
|
||||
deleteCodeFeedbackAPI,
|
||||
deleteCodeFeedbackListAPI,
|
||||
getCodeFeedbackListAPI,
|
||||
postAddCodeFeedbackAPI,
|
||||
putCodeFeedbackAuditAPI,
|
||||
putUpdateCodeFeedbackAPI
|
||||
} from "@/api/code";
|
||||
import { getKeyList, handleTree } from "@pureadmin/utils";
|
||||
import type { DepartmentInfo } from "types/system";
|
||||
import { getDepartmentListAPI } from "@/api/system";
|
||||
|
||||
export const useCode = (tableRef: Ref) => {
|
||||
/**
|
||||
* 查询表单
|
||||
*/
|
||||
const form = reactive({
|
||||
code: "",
|
||||
feedback_code: "",
|
||||
feedback_description: "",
|
||||
username: "",
|
||||
department_id: "",
|
||||
nickname: "",
|
||||
timeRange: [null, null],
|
||||
status: ""
|
||||
});
|
||||
/**
|
||||
* 表单Ref
|
||||
*/
|
||||
const formRef = ref(null);
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
const dataList = ref<CodeFeedbackInfo[]>([]);
|
||||
/**
|
||||
* 加载状态
|
||||
*/
|
||||
const loading = ref(true);
|
||||
/**
|
||||
* 已选数量
|
||||
*/
|
||||
const selectedNum = ref<number>(0);
|
||||
/**
|
||||
* 分页参数
|
||||
*/
|
||||
const pagination = reactive<PaginationProps>({
|
||||
total: 0,
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
background: true,
|
||||
pageSizes: [10, 20, 30, 40, 50]
|
||||
});
|
||||
|
||||
const getStatusTag = (status: number) => {
|
||||
switch (status) {
|
||||
case 1:
|
||||
return "success";
|
||||
case 2:
|
||||
return "danger";
|
||||
case 3:
|
||||
return "warning";
|
||||
default:
|
||||
return "info";
|
||||
}
|
||||
};
|
||||
|
||||
const getStatusTagText = (status: number) => {
|
||||
switch (status) {
|
||||
case 1:
|
||||
return "审核通过";
|
||||
case 2:
|
||||
return "审核未通过";
|
||||
case 3:
|
||||
return "待审核";
|
||||
default:
|
||||
return "未知";
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 表格列设置
|
||||
*/
|
||||
const columns: TableColumnList = [
|
||||
{
|
||||
label: "勾选列", // 如果需要表格多选,此处label必须设置
|
||||
type: "selection",
|
||||
fixed: "left",
|
||||
reserveSelection: true // 数据刷新后保留选项
|
||||
},
|
||||
{
|
||||
label: "用户账号",
|
||||
prop: "username",
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
label: "用户昵称",
|
||||
prop: "nickname",
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
label: "所属部门",
|
||||
prop: "department_name",
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
label: "编码",
|
||||
prop: "code",
|
||||
formatter: ({ code }) => code.replace(/(\d{2})/g, "$1.").slice(0, -1)
|
||||
},
|
||||
{
|
||||
label: "描述",
|
||||
prop: "description"
|
||||
},
|
||||
{
|
||||
label: "反馈编码",
|
||||
prop: "feedback_code"
|
||||
},
|
||||
{
|
||||
label: "反馈描述",
|
||||
prop: "feedback_description"
|
||||
},
|
||||
{
|
||||
label: "审核状态",
|
||||
prop: "status",
|
||||
minWidth: 100,
|
||||
cellRenderer: ({ row, props }) => (
|
||||
<el-tag size={props.size} type={getStatusTag(row.status)}>
|
||||
{getStatusTagText(row.status)}
|
||||
</el-tag>
|
||||
)
|
||||
},
|
||||
{
|
||||
label: "创建时间",
|
||||
prop: "create_time",
|
||||
formatter: ({ create_time }) =>
|
||||
dayjs(create_time).format("YYYY-MM-DD HH:mm:ss")
|
||||
},
|
||||
{
|
||||
label: "操作",
|
||||
fixed: "right",
|
||||
width: 250,
|
||||
slot: "operation"
|
||||
}
|
||||
];
|
||||
/**
|
||||
* 初次查询
|
||||
*/
|
||||
const onSearch = async () => {
|
||||
loading.value = true;
|
||||
const res = await getCodeFeedbackListAPI({
|
||||
page: pagination.currentPage,
|
||||
pageSize: pagination.pageSize,
|
||||
feedback_code: form.feedback_code,
|
||||
feedback_description: form.feedback_description,
|
||||
code: form.code,
|
||||
status: form.status,
|
||||
username: form.username,
|
||||
department_id: form.department_id,
|
||||
nickname: form.nickname,
|
||||
startTime: form.timeRange[0] ? form.timeRange[0] : null,
|
||||
endTime: form.timeRange[1] ? form.timeRange[1] : null
|
||||
});
|
||||
if (res.success) {
|
||||
dataList.value = res.data.result;
|
||||
pagination.total = res.data.total;
|
||||
pagination.currentPage = res.data.page;
|
||||
pagination.pageSize = res.data.pageSize;
|
||||
}
|
||||
message(res.msg, {
|
||||
type: res.success ? "success" : "error"
|
||||
});
|
||||
loading.value = false;
|
||||
};
|
||||
/**
|
||||
* 重置表单
|
||||
* @param formEl 表单ref
|
||||
* @returns
|
||||
*/
|
||||
const resetForm = (formEl: any) => {
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
onSearch();
|
||||
};
|
||||
/**
|
||||
* 处理删除
|
||||
* @param row
|
||||
*/
|
||||
const handleDelete = async (row: CodeFeedbackInfo) => {
|
||||
const res = await deleteCodeFeedbackAPI(row.id);
|
||||
if (res.success) {
|
||||
onSearch();
|
||||
}
|
||||
message(res.msg, {
|
||||
type: res.success ? "success" : "error"
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 处理每页数量变化
|
||||
*/
|
||||
const handleSizeChange = async (val: number) => {
|
||||
const res = await getCodeFeedbackListAPI({
|
||||
page: pagination.currentPage,
|
||||
pageSize: val,
|
||||
feedback_code: form.feedback_code,
|
||||
feedback_description: form.feedback_description,
|
||||
code: form.code,
|
||||
status: form.status,
|
||||
username: form.username,
|
||||
department_id: form.department_id,
|
||||
nickname: form.nickname,
|
||||
startTime: form.timeRange[0] ? form.timeRange[0] : null,
|
||||
endTime: form.timeRange[1] ? form.timeRange[1] : null
|
||||
});
|
||||
if (res.success) {
|
||||
dataList.value = res.data.result;
|
||||
pagination.total = res.data.total;
|
||||
pagination.currentPage = res.data.page;
|
||||
pagination.pageSize = res.data.pageSize;
|
||||
}
|
||||
message(res.msg, {
|
||||
type: res.success ? "success" : "error"
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理页码变化
|
||||
* @param val
|
||||
*/
|
||||
const handleCurrentChange = async (val: number) => {
|
||||
const res = await getCodeFeedbackListAPI({
|
||||
page: val,
|
||||
pageSize: pagination.pageSize,
|
||||
feedback_code: form.feedback_code,
|
||||
feedback_description: form.feedback_description,
|
||||
code: form.code,
|
||||
status: form.status,
|
||||
username: form.username,
|
||||
department_id: form.department_id,
|
||||
nickname: form.nickname,
|
||||
startTime: form.timeRange[0] ? form.timeRange[0] : null,
|
||||
endTime: form.timeRange[1] ? form.timeRange[1] : null
|
||||
});
|
||||
if (res.code === 200) {
|
||||
dataList.value = res.data.result;
|
||||
pagination.total = res.data.total;
|
||||
pagination.currentPage = res.data.page;
|
||||
pagination.pageSize = res.data.pageSize;
|
||||
}
|
||||
message(res.msg, {
|
||||
type: res.success ? "success" : "error"
|
||||
});
|
||||
};
|
||||
/** 当CheckBox选择项发生变化时会触发该事件 */
|
||||
const handleSelectionChange = async (val: any) => {
|
||||
selectedNum.value = val.length;
|
||||
// 重置表格高度
|
||||
tableRef.value.setAdaptive();
|
||||
};
|
||||
|
||||
/** 取消选择 */
|
||||
const onSelectionCancel = async () => {
|
||||
selectedNum.value = 0;
|
||||
// 用于多选表格,清空用户的选择
|
||||
tableRef.value.getTableRef().clearSelection();
|
||||
};
|
||||
/**
|
||||
* 批量删除
|
||||
*/
|
||||
const onbatchDel = async () => {
|
||||
// 返回当前选中的行
|
||||
const curSelected = tableRef.value.getTableRef().getSelectionRows();
|
||||
const res = await deleteCodeFeedbackListAPI({
|
||||
ids: getKeyList(curSelected, "id")
|
||||
});
|
||||
if (res.success) {
|
||||
message(res.msg, {
|
||||
type: "success"
|
||||
});
|
||||
tableRef.value.getTableRef().clearSelection();
|
||||
onSearch();
|
||||
} else {
|
||||
message(res.msg, { type: "error", duration: 5000 });
|
||||
}
|
||||
};
|
||||
const openDialog = async (title = "新增", row?: CodeFeedbackInfo) => {
|
||||
addDialog({
|
||||
title: `${title}编码项`,
|
||||
props: {
|
||||
formInline: {
|
||||
way: title,
|
||||
feedback_code: row?.feedback_code ?? "",
|
||||
feedback_description: row?.feedback_description ?? "",
|
||||
code_id: row?.code_id ?? "",
|
||||
code: row?.code ?? "",
|
||||
description: row?.description ?? "",
|
||||
status: row?.status ?? 3,
|
||||
user_id: row?.user_id ?? "",
|
||||
username: row?.username ?? "",
|
||||
nickname: row?.nickname ?? "",
|
||||
department_id: row?.department_id ?? "",
|
||||
department_name: row?.department_name ?? "",
|
||||
id: row?.id ?? "",
|
||||
create_time: row?.create_time ?? "",
|
||||
update_time: row?.update_time ?? ""
|
||||
}
|
||||
},
|
||||
width: "45%",
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () =>
|
||||
h(editForm, {
|
||||
formInline: {
|
||||
way: title,
|
||||
feedback_description: row?.feedback_description ?? "",
|
||||
feedback_code: row?.feedback_code ?? "",
|
||||
code_id: row?.code_id ?? "",
|
||||
code: row?.code ?? "",
|
||||
description: row?.description ?? "",
|
||||
status: row?.status ?? 3,
|
||||
user_id: row?.user_id ?? "",
|
||||
username: row?.username ?? "",
|
||||
nickname: row?.nickname ?? "",
|
||||
department_id: row?.department_id ?? "",
|
||||
department_name: row?.department_name ?? "",
|
||||
id: row?.id ?? "",
|
||||
create_time: row?.create_time ?? "",
|
||||
update_time: row?.update_time ?? ""
|
||||
},
|
||||
ref: formRef
|
||||
}),
|
||||
beforeSure: async (done, {}) => {
|
||||
const FormData = formRef.value.newFormInline;
|
||||
let form = {
|
||||
feedback_description: FormData.feedback_description ?? "",
|
||||
feedback_code: FormData.feedback_code ?? "",
|
||||
code_id: FormData.code_id ?? ""
|
||||
};
|
||||
if (title === "新增") {
|
||||
const res = await postAddCodeFeedbackAPI(form);
|
||||
if (res.success) {
|
||||
done();
|
||||
await onSearch();
|
||||
}
|
||||
message(res.msg, { type: res.success ? "success" : "error" });
|
||||
} else {
|
||||
const res = await putUpdateCodeFeedbackAPI(form, row.id);
|
||||
if (res.success) {
|
||||
done();
|
||||
await onSearch();
|
||||
}
|
||||
message(res.msg, { type: res.success ? "success" : "error" });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**部门列表 */
|
||||
const departments = ref<DepartmentInfo[]>([]);
|
||||
/**获取部门列表 */
|
||||
const getDepartments = async () => {
|
||||
const res = await getDepartmentListAPI({ page: 1, pageSize: 9999 });
|
||||
if (res.success) {
|
||||
departments.value = formatHigherOptions(
|
||||
handleTree(res.data.result, "id", "parent_id")
|
||||
);
|
||||
} else {
|
||||
departments.value = [];
|
||||
}
|
||||
};
|
||||
const formatHigherOptions = (treeList: any) => {
|
||||
// 根据返回数据的status字段值判断追加是否禁用disabled字段,返回处理后的树结构,用于上级部门级联选择器的展示(实际开发中也是如此,不可能前端需要的每个字段后端都会返回,这时需要前端自行根据后端返回的某些字段做逻辑处理)
|
||||
if (!treeList || !treeList.length) return;
|
||||
const newTreeList = [];
|
||||
for (let i = 0; i < treeList.length; i++) {
|
||||
treeList[i].disabled = treeList[i].status === 0 ? true : false;
|
||||
formatHigherOptions(treeList[i].children);
|
||||
newTreeList.push(treeList[i]);
|
||||
}
|
||||
return newTreeList;
|
||||
};
|
||||
/** 处理审核 */
|
||||
const handleAudit = async (row: CodeFeedbackInfo) => {
|
||||
addDialog({
|
||||
title: `审核编码项`,
|
||||
props: {
|
||||
formInline: {
|
||||
way: "审核",
|
||||
feedback_code: row?.feedback_code ?? "",
|
||||
feedback_description: row?.feedback_description ?? "",
|
||||
code_id: row?.code_id ?? "",
|
||||
code: row?.code ?? "",
|
||||
description: row?.description ?? "",
|
||||
status: row?.status ?? 3,
|
||||
user_id: row?.user_id ?? "",
|
||||
username: row?.username ?? "",
|
||||
nickname: row?.nickname ?? "",
|
||||
department_id: row?.department_id ?? "",
|
||||
department_name: row?.department_name ?? "",
|
||||
id: row?.id ?? "",
|
||||
create_time: row?.create_time ?? "",
|
||||
update_time: row?.update_time ?? ""
|
||||
}
|
||||
},
|
||||
width: "45%",
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
|
||||
contentRenderer: () =>
|
||||
h(editForm, {
|
||||
formInline: {
|
||||
way: "审核",
|
||||
feedback_code: row?.feedback_code ?? "",
|
||||
feedback_description: row?.feedback_description ?? "",
|
||||
code_id: row?.code_id ?? "",
|
||||
code: row?.code ?? "",
|
||||
description: row?.description ?? "",
|
||||
status: row?.status ?? 3,
|
||||
user_id: row?.user_id ?? "",
|
||||
username: row?.username ?? "",
|
||||
nickname: row?.nickname ?? "",
|
||||
department_id: row?.department_id ?? "",
|
||||
department_name: row?.department_name ?? "",
|
||||
id: row?.id ?? "",
|
||||
create_time: row?.create_time ?? "",
|
||||
update_time: row?.update_time ?? ""
|
||||
},
|
||||
ref: formRef
|
||||
}),
|
||||
|
||||
footerButtons: [
|
||||
{
|
||||
label: "取消",
|
||||
type: "info",
|
||||
btnClick: ({ dialog }) => {
|
||||
console.log("取消审核");
|
||||
closeDialog(dialog.options!, dialog.index!); // ✅ 调用封装的 `closeDialog`
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "通过",
|
||||
type: "success",
|
||||
popconfirm: {
|
||||
title: "确定要通过审核吗?",
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消"
|
||||
},
|
||||
btnClick: async ({ dialog }) => {
|
||||
const res = await putCodeFeedbackAuditAPI({
|
||||
status: 1,
|
||||
ids: [row.id]
|
||||
});
|
||||
if (res.success) {
|
||||
closeDialog(dialog.options!, dialog.index!); // ✅ 调用封装的 `closeDialog`
|
||||
await onSearch();
|
||||
}
|
||||
message(res.msg, { type: res.success ? "success" : "error" });
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "不通过",
|
||||
type: "danger",
|
||||
popconfirm: {
|
||||
title: "确定要驳回审核吗?",
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消"
|
||||
},
|
||||
btnClick: async ({ dialog }) => {
|
||||
const res = await putCodeFeedbackAuditAPI({
|
||||
status: 2,
|
||||
ids: [row.id]
|
||||
});
|
||||
if (res.success) {
|
||||
closeDialog(dialog.options!, dialog.index!); // ✅ 调用封装的 `closeDialog`
|
||||
await onSearch();
|
||||
}
|
||||
message(res.msg, { type: res.success ? "success" : "error" });
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
/**批量通过 */
|
||||
const onbatchAgree = async () => {
|
||||
// 返回当前选中的行
|
||||
const curSelected = tableRef.value.getTableRef().getSelectionRows();
|
||||
const res = await putCodeFeedbackAuditAPI({
|
||||
status: 1,
|
||||
ids: getKeyList(curSelected, "id")
|
||||
});
|
||||
if (res.success) {
|
||||
message(res.msg, {
|
||||
type: "success"
|
||||
});
|
||||
tableRef.value.getTableRef().clearSelection();
|
||||
onSearch();
|
||||
} else {
|
||||
message(res.msg, { type: "error", duration: 5000 });
|
||||
}
|
||||
};
|
||||
/**批量驳回 */
|
||||
const onbatchDisagree = async () => {
|
||||
// 返回当前选中的行
|
||||
const curSelected = tableRef.value.getTableRef().getSelectionRows();
|
||||
const res = await putCodeFeedbackAuditAPI({
|
||||
status: 2,
|
||||
ids: getKeyList(curSelected, "id")
|
||||
});
|
||||
if (res.success) {
|
||||
message(res.msg, {
|
||||
type: "success"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 页面加载执行
|
||||
*/
|
||||
onMounted(async () => {
|
||||
await onSearch();
|
||||
await getDepartments();
|
||||
});
|
||||
return {
|
||||
form,
|
||||
dataList,
|
||||
loading,
|
||||
pagination,
|
||||
columns,
|
||||
selectedNum,
|
||||
departments,
|
||||
openDialog,
|
||||
onSearch,
|
||||
resetForm,
|
||||
handleDelete,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
handleSelectionChange,
|
||||
onSelectionCancel,
|
||||
onbatchDel,
|
||||
handleAudit,
|
||||
onbatchDisagree,
|
||||
onbatchAgree
|
||||
};
|
||||
};
|
180
src/views/data/import/components/form.vue
Normal file
180
src/views/data/import/components/form.vue
Normal file
@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
:model="newFormInline"
|
||||
:rules="formRules"
|
||||
label-width="82px"
|
||||
>
|
||||
<el-row :gutter="30">
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="编码" prop="code">
|
||||
<el-input
|
||||
v-model="newFormInline.code"
|
||||
placeholder="请输入编码~"
|
||||
clearable
|
||||
:disabled="newFormInline.way === '审核'"
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input
|
||||
v-model="newFormInline.description"
|
||||
placeholder="请输入编码描述~"
|
||||
clearable
|
||||
:disabled="newFormInline.way === '审核'"
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="用户ID" prop="user_id">
|
||||
<el-input
|
||||
v-model="newFormInline.user_id"
|
||||
placeholder="请输入用户ID~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="用户账号" prop="username">
|
||||
<el-input
|
||||
v-model="newFormInline.username"
|
||||
placeholder="请输入用户账号~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="用户名称" prop="nickname">
|
||||
<el-input
|
||||
v-model="newFormInline.nickname"
|
||||
placeholder="请输入用户名称~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="所属部门" prop="department_name">
|
||||
<el-input
|
||||
v-model="newFormInline.department_name"
|
||||
placeholder="请输入所属部门~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="创建时间" prop="create_time">
|
||||
<el-input
|
||||
:value="
|
||||
dayjs(newFormInline.create_time).format('YYYY-MM-DD HH:mm:ss')
|
||||
"
|
||||
placeholder="请输入创建时间~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="修改时间" prop="update_time">
|
||||
<el-input
|
||||
:value="
|
||||
dayjs(newFormInline.update_time).format('YYYY-MM-DD HH:mm:ss')
|
||||
"
|
||||
placeholder="请输入修改时间~"
|
||||
disabled
|
||||
clearable
|
||||
class="w-full"
|
||||
/>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
<re-col v-if="newFormInline.way !== '新增'" :value="24" :xm="24" :sm="24">
|
||||
<el-form-item label="审核状态" prop="status">
|
||||
<el-select
|
||||
v-model="newFormInline.status"
|
||||
placeholder="请选择状态~"
|
||||
clearable
|
||||
disabled
|
||||
class="w-[full]"
|
||||
>
|
||||
<el-option label="审核通过" :value="1" />
|
||||
<el-option label="审核未通过" :value="2" />
|
||||
<el-option label="待审核" :value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import dayjs from "dayjs";
|
||||
import { ref, reactive } from "vue";
|
||||
import ReCol from "@/components/ReCol";
|
||||
import type { FormRules } from "element-plus";
|
||||
const ruleFormRef = ref();
|
||||
interface PropsInfo {
|
||||
id: string;
|
||||
/**方式 */
|
||||
way: string;
|
||||
/**导入状态 */
|
||||
status: number;
|
||||
/**编码 */
|
||||
code: string;
|
||||
/**编码描述 */
|
||||
description: string;
|
||||
/** 创建时间 */
|
||||
create_time: string;
|
||||
/** 更新时间 */
|
||||
update_time: string;
|
||||
/**用户ID */
|
||||
user_id: string;
|
||||
/**用户昵称 */
|
||||
nickname: string;
|
||||
/**用户账号 */
|
||||
username: string;
|
||||
/**部门ID */
|
||||
department_id: string;
|
||||
/**部门名称 */
|
||||
department_name: string;
|
||||
}
|
||||
|
||||
type ProsData = {
|
||||
formInline: PropsInfo;
|
||||
};
|
||||
/** 自定义表单规则校验 */
|
||||
const formRules = reactive<FormRules>({
|
||||
code: [{ required: true, message: "编码为必填项", trigger: "blur" }],
|
||||
description: [
|
||||
{ required: true, message: "编码描述为必填项", trigger: "blur" }
|
||||
]
|
||||
});
|
||||
const props = withDefaults(defineProps<ProsData>(), {
|
||||
formInline: () => ({
|
||||
id: "",
|
||||
way: "新增",
|
||||
code: "",
|
||||
description: "",
|
||||
status: 0,
|
||||
create_time: "",
|
||||
update_time: "",
|
||||
user_id: "",
|
||||
nickname: "",
|
||||
username: "",
|
||||
department_id: "",
|
||||
department_name: ""
|
||||
})
|
||||
});
|
||||
const newFormInline = ref<PropsInfo>(props.formInline);
|
||||
defineExpose({ newFormInline });
|
||||
</script>
|
375
src/views/data/import/index.vue
Normal file
375
src/views/data/import/index.vue
Normal file
@ -0,0 +1,375 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:inline="true"
|
||||
:model="form"
|
||||
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]"
|
||||
>
|
||||
<el-form-item label="用户账号" prop="usename">
|
||||
<el-input
|
||||
v-model="form.username"
|
||||
placeholder="请输入用户账号~"
|
||||
clearable
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名称" prop="nickname">
|
||||
<el-input
|
||||
v-model="form.nickname"
|
||||
placeholder="请输入用户昵称~"
|
||||
clearable
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="编码" prop="code">
|
||||
<el-input
|
||||
v-model="form.code"
|
||||
placeholder="请输入编码"
|
||||
clearable
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="编码描述" prop="description">
|
||||
<el-input
|
||||
v-model="form.description"
|
||||
clearable
|
||||
placeholder="请输入编码描述~"
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="hasAuth('code:data:importAdmin')"
|
||||
label="所属部门:"
|
||||
prop="department_id"
|
||||
>
|
||||
<el-cascader
|
||||
v-model="form.department_id"
|
||||
class="!w-[200px]"
|
||||
:options="departments"
|
||||
:props="{
|
||||
value: 'id',
|
||||
label: 'name',
|
||||
emitPath: false,
|
||||
checkStrictly: true
|
||||
}"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择所属部门~"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span>{{ data.name }}</span>
|
||||
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
||||
</template>
|
||||
</el-cascader>
|
||||
</el-form-item>
|
||||
<el-form-item label="导入时间" prop="timeRange">
|
||||
<el-date-picker
|
||||
v-model="form.timeRange"
|
||||
:shortcuts="getPickerShortcuts()"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期时间"
|
||||
end-placeholder="结束日期时间"
|
||||
value-format="x"
|
||||
unlink-panels
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="useRenderIcon('ri:search-line')"
|
||||
:loading="loading"
|
||||
@click="onSearch"
|
||||
>
|
||||
{{ t("buttons:Search") }}
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
|
||||
{{ t("buttons:Reset") }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<PureTableBar title="编码导入" :columns="columns" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button
|
||||
v-if="hasAuth('code:btn:add')"
|
||||
type="primary"
|
||||
:disabled="!hasAuth('code:btn:add')"
|
||||
:icon="useRenderIcon(AddFill)"
|
||||
@click="openDialog('新增')"
|
||||
>
|
||||
{{ t("buttons:Add") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hasAuth('code:btn:import')"
|
||||
type="primary"
|
||||
:icon="useRenderIcon(AddFill)"
|
||||
:disabled="!hasAuth('code:btn:import')"
|
||||
@click="showUploadArea = !showUploadArea"
|
||||
>
|
||||
{{ showUploadArea ? t("buttons:Hide") : t("buttons:Import") }}
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-slot="{ size, dynamicColumns }">
|
||||
<!-- 上传文件区域 -->
|
||||
<el-card v-if="showUploadArea" shadow="never">
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
v-model:file-list="fileList"
|
||||
drag
|
||||
action="#"
|
||||
class="w-full"
|
||||
:auto-upload="false"
|
||||
:before-upload="beforeUpload"
|
||||
:before-remove="beforeRemove"
|
||||
>
|
||||
<div class="el-upload__text">
|
||||
<IconifyIconOffline
|
||||
:icon="UploadIcon"
|
||||
width="26"
|
||||
:limit="1"
|
||||
class="m-auto mb-2"
|
||||
/>
|
||||
可点击或拖拽上传
|
||||
</div>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<div class="flex items-center justify-center">
|
||||
<el-button
|
||||
v-if="hasAuth('code:btn:uploadTemplate')"
|
||||
class="w-full my-2"
|
||||
:disabled="!hasAuth('code:btn:uploadTemplate')"
|
||||
@click="onDownloadTemplate"
|
||||
>{{ t("buttons:DownLodedTemplate") }}</el-button
|
||||
>
|
||||
<el-popconfirm
|
||||
v-if="hasAuth('code:btn:import')"
|
||||
title="是否确认上传?"
|
||||
@confirm="handleUpload"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
class="w-full my-2"
|
||||
type="primary"
|
||||
:disabled="uploadStatus || !hasAuth('code:btn:import')"
|
||||
>{{ t("buttons:ConfirmUpload") }}</el-button
|
||||
>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</div>
|
||||
</template>
|
||||
</el-card>
|
||||
<div
|
||||
v-if="selectedNum > 0"
|
||||
v-motion-fade
|
||||
class="bg-[var(--el-fill-color-light)] w-full h-[46px] mb-2 pl-4 flex items-center"
|
||||
>
|
||||
<div class="flex-auto">
|
||||
<span
|
||||
style="font-size: var(--el-font-size-base)"
|
||||
class="text-[rgba(42,46,54,0.5)] dark:text-[rgba(220,220,242,0.5)]"
|
||||
>
|
||||
已选 {{ selectedNum }} 项
|
||||
</span>
|
||||
<el-button type="primary" text @click="onSelectionCancel">
|
||||
{{ t("buttons:Deselect") }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-popconfirm
|
||||
v-if="hasAuth('code:btn:codeImportAudit')"
|
||||
title="是否确认通过审核?"
|
||||
@confirm="onbatchAgree"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
type="success"
|
||||
text
|
||||
class="mr-1"
|
||||
:disabled="
|
||||
selectedNum < 0 || !hasAuth('code:btn:codeImportAudit')
|
||||
"
|
||||
>
|
||||
{{ t("buttons:AgressInBatches") }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-popconfirm
|
||||
v-if="hasAuth('code:btn:codeImportAudit')"
|
||||
title="是否确认驳回?"
|
||||
@confirm="onbatchDisagree"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
type="danger"
|
||||
text
|
||||
class="mr-1"
|
||||
:disabled="
|
||||
selectedNum < 0 || !hasAuth('code:btn:codeImportAudit')
|
||||
"
|
||||
>
|
||||
{{ t("buttons:DisagressInBatches") }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-popconfirm
|
||||
v-if="hasAuth('code:btn:deleteCodeImport')"
|
||||
title="是否确认删除?"
|
||||
@confirm="onbatchDel"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
type="danger"
|
||||
text
|
||||
class="mr-1"
|
||||
:disabled="
|
||||
selectedNum < 0 || !hasAuth('code:btn:deleteCodeImport')
|
||||
"
|
||||
>
|
||||
{{ t("buttons:DeleteInBatches") }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</div>
|
||||
<pure-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
adaptive
|
||||
border
|
||||
stripe
|
||||
:adaptiveConfig="{ offsetBottom: 45 }"
|
||||
align-whole="center"
|
||||
table-layout="auto"
|
||||
:loading="loading"
|
||||
:size="size"
|
||||
:data="dataList"
|
||||
:columns="dynamicColumns"
|
||||
:pagination="pagination"
|
||||
:paginationSmall="size === 'small' ? true : false"
|
||||
:header-cell-style="{
|
||||
background: 'var(--el-fill-color-light)',
|
||||
color: 'var(--el-text-color-primary)'
|
||||
}"
|
||||
@selection-change="handleSelectionChange"
|
||||
@page-size-change="handleSizeChange"
|
||||
@page-current-change="handleCurrentChange"
|
||||
>
|
||||
<template #operation="{ row }">
|
||||
<el-button
|
||||
class="reset-margin"
|
||||
link
|
||||
type="primary"
|
||||
:size="size"
|
||||
:disabled="!hasAuth('code:btn:updateCodeImport')"
|
||||
:icon="useRenderIcon(EditPen)"
|
||||
@click="openDialog('修改', row)"
|
||||
>
|
||||
{{ t("buttons:Update") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="reset-margin"
|
||||
link
|
||||
type="warning"
|
||||
:size="size"
|
||||
:disabled="!hasAuth('code:btn:codeImportAudit')"
|
||||
:icon="useRenderIcon(Read)"
|
||||
@click="handleAudit(row)"
|
||||
>
|
||||
{{ t("buttons:Audit") }}
|
||||
</el-button>
|
||||
<el-popconfirm
|
||||
:title="`是否确认删除编码名为 ${row.code} 的这条数据`"
|
||||
@confirm="handleDelete(row)"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
class="reset-margin"
|
||||
link
|
||||
type="danger"
|
||||
:size="size"
|
||||
:disabled="!hasAuth('code:btn:deleteCodeImport')"
|
||||
:icon="useRenderIcon(Delete)"
|
||||
>
|
||||
{{ t("buttons:Delete") }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</pure-table>
|
||||
</template>
|
||||
</PureTableBar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: "DataImport"
|
||||
});
|
||||
import { ref } from "vue";
|
||||
import { useCode } from "./utils/hook";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { getPickerShortcuts } from "@/views/monitor/utils";
|
||||
import { PureTableBar } from "@/components/RePureTableBar";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import Delete from "@iconify-icons/ep/delete";
|
||||
import EditPen from "@iconify-icons/ep/edit-pen";
|
||||
import Refresh from "@iconify-icons/ep/refresh";
|
||||
import AddFill from "@iconify-icons/ri/add-circle-line";
|
||||
import UploadIcon from "@iconify-icons/ri/upload-2-line";
|
||||
import Read from "@iconify-icons/ep/place";
|
||||
import { hasAuth } from "@/utils/auth";
|
||||
const { t } = useI18n();
|
||||
|
||||
/**
|
||||
* 表格Ref
|
||||
*/
|
||||
const tableRef = ref();
|
||||
const formRef = ref();
|
||||
const {
|
||||
form,
|
||||
dataList,
|
||||
loading,
|
||||
pagination,
|
||||
columns,
|
||||
selectedNum,
|
||||
showUploadArea,
|
||||
departments,
|
||||
fileList,
|
||||
uploadStatus,
|
||||
beforeUpload,
|
||||
handleUpload,
|
||||
beforeRemove,
|
||||
openDialog,
|
||||
onSearch,
|
||||
resetForm,
|
||||
handleDelete,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
handleSelectionChange,
|
||||
onSelectionCancel,
|
||||
onbatchDel,
|
||||
onDownloadTemplate,
|
||||
handleAudit,
|
||||
onbatchDisagree,
|
||||
onbatchAgree
|
||||
} = useCode(tableRef);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.el-dropdown-menu__item i) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:deep(.el-button:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin: 24px 24px 0 !important;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
659
src/views/data/import/utils/hook.tsx
Normal file
659
src/views/data/import/utils/hook.tsx
Normal file
@ -0,0 +1,659 @@
|
||||
import dayjs from "dayjs";
|
||||
import editForm from "../components/form.vue";
|
||||
import { message } from "@/utils/message";
|
||||
import { type Ref, ref, reactive, onMounted, h } from "vue";
|
||||
import { addDialog, closeDialog } from "@/components/ReDialog";
|
||||
import type { PaginationProps } from "@pureadmin/table";
|
||||
import type { CodeImportInfo } from "types/code";
|
||||
import {
|
||||
deleteCodeImportAPI,
|
||||
deleteCodeImportListAPI,
|
||||
getAddCodeAPI,
|
||||
getCodeImportListAPI,
|
||||
getCodeTemplateAPI,
|
||||
postAddCodeAPI,
|
||||
putCodeImportAuditAPI,
|
||||
putUpdateCodeImportAPI
|
||||
} from "@/api/code";
|
||||
import { getKeyList, handleTree } from "@pureadmin/utils";
|
||||
import {
|
||||
ElMessageBox,
|
||||
type UploadProps,
|
||||
type UploadUserFile
|
||||
} from "element-plus";
|
||||
import { deleteFileAPI, postUploadFileAPI } from "@/api/file";
|
||||
import type { DepartmentInfo } from "types/system";
|
||||
import { getDepartmentListAPI } from "@/api/system";
|
||||
|
||||
export const useCode = (tableRef: Ref) => {
|
||||
/**
|
||||
* 查询表单
|
||||
*/
|
||||
const form = reactive({
|
||||
code: "",
|
||||
description: "",
|
||||
username: "",
|
||||
department_id: "",
|
||||
nickname: "",
|
||||
timeRange: [null, null],
|
||||
status: ""
|
||||
});
|
||||
/**
|
||||
* 表单Ref
|
||||
*/
|
||||
const formRef = ref(null);
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
const dataList = ref<CodeImportInfo[]>([]);
|
||||
/**
|
||||
* 加载状态
|
||||
*/
|
||||
const loading = ref(true);
|
||||
/**
|
||||
* 已选数量
|
||||
*/
|
||||
const selectedNum = ref<number>(0);
|
||||
/**
|
||||
* 分页参数
|
||||
*/
|
||||
const pagination = reactive<PaginationProps>({
|
||||
total: 0,
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
background: true,
|
||||
pageSizes: [10, 20, 30, 40, 50]
|
||||
});
|
||||
// 上传文件区域显示状态
|
||||
const showUploadArea = ref(false);
|
||||
const fileList = ref<UploadUserFile[]>([]);
|
||||
/**上传成功后文件列表 */
|
||||
const fileIds = ref([]);
|
||||
const fileId = ref<string>("");
|
||||
/**上传按钮状态 */
|
||||
const uploadStatus = ref<boolean>(false);
|
||||
|
||||
const getStatusTag = (status: number) => {
|
||||
switch (status) {
|
||||
case 1:
|
||||
return "success";
|
||||
case 2:
|
||||
return "danger";
|
||||
case 3:
|
||||
return "warning";
|
||||
default:
|
||||
return "info";
|
||||
}
|
||||
};
|
||||
|
||||
const getStatusTagText = (status: number) => {
|
||||
switch (status) {
|
||||
case 1:
|
||||
return "审核通过";
|
||||
case 2:
|
||||
return "审核未通过";
|
||||
case 3:
|
||||
return "待审核";
|
||||
default:
|
||||
return "未知";
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 表格列设置
|
||||
*/
|
||||
const columns: TableColumnList = [
|
||||
{
|
||||
label: "勾选列", // 如果需要表格多选,此处label必须设置
|
||||
type: "selection",
|
||||
fixed: "left",
|
||||
reserveSelection: true // 数据刷新后保留选项
|
||||
},
|
||||
{
|
||||
label: "用户账号",
|
||||
prop: "username",
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
label: "用户昵称",
|
||||
prop: "nickname",
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
label: "所属部门",
|
||||
prop: "department_name",
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
label: "编码",
|
||||
prop: "code",
|
||||
formatter: ({ code }) => code.replace(/(\d{2})/g, "$1.").slice(0, -1)
|
||||
},
|
||||
{
|
||||
label: "编码描述",
|
||||
prop: "description"
|
||||
},
|
||||
{
|
||||
label: "审核状态",
|
||||
prop: "status",
|
||||
minWidth: 100,
|
||||
cellRenderer: ({ row, props }) => (
|
||||
<el-tag size={props.size} type={getStatusTag(row.status)}>
|
||||
{getStatusTagText(row.status)}
|
||||
</el-tag>
|
||||
)
|
||||
},
|
||||
{
|
||||
label: "创建时间",
|
||||
prop: "create_time",
|
||||
formatter: ({ create_time }) =>
|
||||
dayjs(create_time).format("YYYY-MM-DD HH:mm:ss")
|
||||
},
|
||||
{
|
||||
label: "操作",
|
||||
fixed: "right",
|
||||
width: 250,
|
||||
slot: "operation"
|
||||
}
|
||||
];
|
||||
/**
|
||||
* 初次查询
|
||||
*/
|
||||
const onSearch = async () => {
|
||||
loading.value = true;
|
||||
const res = await getCodeImportListAPI({
|
||||
page: pagination.currentPage,
|
||||
pageSize: pagination.pageSize,
|
||||
description: form.description,
|
||||
code: form.code,
|
||||
status: form.status,
|
||||
username: form.username,
|
||||
department_id: form.department_id,
|
||||
nickname: form.nickname,
|
||||
startTime: form.timeRange[0] ? form.timeRange[0] : null,
|
||||
endTime: form.timeRange[1] ? form.timeRange[1] : null
|
||||
});
|
||||
if (res.success) {
|
||||
dataList.value = res.data.result;
|
||||
pagination.total = res.data.total;
|
||||
pagination.currentPage = res.data.page;
|
||||
pagination.pageSize = res.data.pageSize;
|
||||
}
|
||||
message(res.msg, {
|
||||
type: res.success ? "success" : "error"
|
||||
});
|
||||
loading.value = false;
|
||||
};
|
||||
/**
|
||||
* 重置表单
|
||||
* @param formEl 表单ref
|
||||
* @returns
|
||||
*/
|
||||
const resetForm = (formEl: any) => {
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
onSearch();
|
||||
};
|
||||
/**
|
||||
* 处理删除
|
||||
* @param row
|
||||
*/
|
||||
const handleDelete = async (row: CodeImportInfo) => {
|
||||
const res = await deleteCodeImportAPI(row.id);
|
||||
if (res.success) {
|
||||
onSearch();
|
||||
}
|
||||
message(res.msg, {
|
||||
type: res.success ? "success" : "error"
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 处理每页数量变化
|
||||
*/
|
||||
const handleSizeChange = async (val: number) => {
|
||||
const res = await getCodeImportListAPI({
|
||||
page: pagination.currentPage,
|
||||
pageSize: val,
|
||||
description: form.description,
|
||||
code: form.code,
|
||||
status: form.status,
|
||||
username: form.username,
|
||||
department_id: form.department_id,
|
||||
nickname: form.nickname,
|
||||
startTime: form.timeRange[0] ? form.timeRange[0] : null,
|
||||
endTime: form.timeRange[1] ? form.timeRange[1] : null
|
||||
});
|
||||
if (res.success) {
|
||||
dataList.value = res.data.result;
|
||||
pagination.total = res.data.total;
|
||||
pagination.currentPage = res.data.page;
|
||||
pagination.pageSize = res.data.pageSize;
|
||||
}
|
||||
message(res.msg, {
|
||||
type: res.success ? "success" : "error"
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理页码变化
|
||||
* @param val
|
||||
*/
|
||||
const handleCurrentChange = async (val: number) => {
|
||||
const res = await getCodeImportListAPI({
|
||||
page: val,
|
||||
pageSize: pagination.pageSize,
|
||||
description: form.description,
|
||||
code: form.code,
|
||||
status: form.status,
|
||||
username: form.username,
|
||||
department_id: form.department_id,
|
||||
nickname: form.nickname,
|
||||
startTime: form.timeRange[0] ? form.timeRange[0] : null,
|
||||
endTime: form.timeRange[1] ? form.timeRange[1] : null
|
||||
});
|
||||
if (res.code === 200) {
|
||||
dataList.value = res.data.result;
|
||||
pagination.total = res.data.total;
|
||||
pagination.currentPage = res.data.page;
|
||||
pagination.pageSize = res.data.pageSize;
|
||||
}
|
||||
message(res.msg, {
|
||||
type: res.success ? "success" : "error"
|
||||
});
|
||||
};
|
||||
/** 当CheckBox选择项发生变化时会触发该事件 */
|
||||
const handleSelectionChange = async (val: any) => {
|
||||
selectedNum.value = val.length;
|
||||
// 重置表格高度
|
||||
tableRef.value.setAdaptive();
|
||||
};
|
||||
|
||||
/** 取消选择 */
|
||||
const onSelectionCancel = async () => {
|
||||
selectedNum.value = 0;
|
||||
// 用于多选表格,清空用户的选择
|
||||
tableRef.value.getTableRef().clearSelection();
|
||||
};
|
||||
/**
|
||||
* 批量删除
|
||||
*/
|
||||
const onbatchDel = async () => {
|
||||
// 返回当前选中的行
|
||||
const curSelected = tableRef.value.getTableRef().getSelectionRows();
|
||||
const res = await deleteCodeImportListAPI({
|
||||
ids: getKeyList(curSelected, "id")
|
||||
});
|
||||
if (res.success) {
|
||||
message(res.msg, {
|
||||
type: "success"
|
||||
});
|
||||
tableRef.value.getTableRef().clearSelection();
|
||||
onSearch();
|
||||
} else {
|
||||
message(res.msg, { type: "error", duration: 5000 });
|
||||
}
|
||||
};
|
||||
const openDialog = async (title = "新增", row?: CodeImportInfo) => {
|
||||
addDialog({
|
||||
title: `${title}编码项`,
|
||||
props: {
|
||||
formInline: {
|
||||
way: title,
|
||||
description: row?.description ?? "",
|
||||
code: row?.code ?? "",
|
||||
status: row?.status ?? 3,
|
||||
user_id: row?.user_id ?? "",
|
||||
username: row?.username ?? "",
|
||||
nickname: row?.nickname ?? "",
|
||||
department_id: row?.department_id ?? "",
|
||||
department_name: row?.department_name ?? "",
|
||||
id: row?.id ?? "",
|
||||
create_time: row?.create_time ?? "",
|
||||
update_time: row?.update_time ?? ""
|
||||
}
|
||||
},
|
||||
width: "45%",
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
contentRenderer: () =>
|
||||
h(editForm, {
|
||||
formInline: {
|
||||
way: title,
|
||||
description: row?.description ?? "",
|
||||
code: row?.code ?? "",
|
||||
status: row?.status ?? 3,
|
||||
user_id: row?.user_id ?? "",
|
||||
username: row?.username ?? "",
|
||||
nickname: row?.nickname ?? "",
|
||||
department_id: row?.department_id ?? "",
|
||||
department_name: row?.department_name ?? "",
|
||||
id: row?.id ?? "",
|
||||
create_time: row?.create_time ?? "",
|
||||
update_time: row?.update_time ?? ""
|
||||
},
|
||||
ref: formRef
|
||||
}),
|
||||
beforeSure: async (done, {}) => {
|
||||
const FormData = formRef.value.newFormInline;
|
||||
let form = {
|
||||
description: FormData.description ?? "",
|
||||
code: FormData.code ?? ""
|
||||
};
|
||||
if (title === "新增") {
|
||||
const res = await postAddCodeAPI(form);
|
||||
if (res.success) {
|
||||
done();
|
||||
await onSearch();
|
||||
}
|
||||
message(res.msg, { type: res.success ? "success" : "error" });
|
||||
} else {
|
||||
const res = await putUpdateCodeImportAPI(form, row.id);
|
||||
if (res.success) {
|
||||
done();
|
||||
await onSearch();
|
||||
}
|
||||
message(res.msg, { type: res.success ? "success" : "error" });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
/**下载模版文件 */
|
||||
const onDownloadTemplate = async () => {
|
||||
try {
|
||||
const blob = await getCodeTemplateAPI();
|
||||
|
||||
// 生成下载链接
|
||||
// @ts-ignore
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
// 创建 <a> 元素并触发下载
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = "上传模版.xlsx"; // 设置下载文件名,确保后缀名正确
|
||||
document.body.appendChild(link); // 将 <a> 元素添加到 DOM 中
|
||||
link.click(); // 模拟点击下载
|
||||
|
||||
// 清理 URL 对象
|
||||
URL.revokeObjectURL(url);
|
||||
document.body.removeChild(link); // 移除 <a> 元素
|
||||
} catch (error) {
|
||||
console.error("下载模板失败:", error);
|
||||
}
|
||||
};
|
||||
/** 上传文件前 */
|
||||
const beforeUpload = async file => {
|
||||
const isExcel =
|
||||
file.type ===
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" || // xlsx
|
||||
file.type === "application/vnd.ms-excel" || // xls
|
||||
file.name.endsWith(".xlsx") || // 兼容部分浏览器
|
||||
file.name.endsWith(".xls"); // 兼容部分浏览器
|
||||
|
||||
// const maxSize = 20 * 1024 * 1024; // 20MB 限制
|
||||
|
||||
if (!isExcel) {
|
||||
message("只能上传 xlsx 或 xls 文件!", { type: "error" });
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
if (file.size > maxSize) {
|
||||
message("文件大小应在 20MB 以内!", { type: "error" });
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**处理文件上传 */
|
||||
const handleUpload = async () => {
|
||||
if (fileList.value.length === 0) {
|
||||
message("请先上传文件!", { type: "error", duration: 5000 });
|
||||
return;
|
||||
}
|
||||
uploadStatus.value = true;
|
||||
for (const file of fileList.value) {
|
||||
if (file.status === "success") {
|
||||
const data = await getAddCodeAPI(fileId.value);
|
||||
if (data.success) {
|
||||
message("导入成功!", { type: "success" });
|
||||
await onSearch();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
const res = await postUploadFileAPI({
|
||||
file: file.raw
|
||||
});
|
||||
if (res.success) {
|
||||
file.status = "success";
|
||||
fileId.value = res.data.id;
|
||||
message(`${res.data.name}上传成功!`, { type: "success" });
|
||||
fileIds.value.push(res.data);
|
||||
const data = await getAddCodeAPI(fileId.value);
|
||||
if (data.success) {
|
||||
message(`导入成功!`, { type: "success" });
|
||||
await onSearch();
|
||||
}
|
||||
} else {
|
||||
file.status = "fail";
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
uploadStatus.value = false;
|
||||
};
|
||||
/**移除文件 */
|
||||
const beforeRemove: UploadProps["beforeRemove"] = async uploadFile => {
|
||||
return ElMessageBox.confirm(`是否移除 ${uploadFile.name} ?`).then(
|
||||
async () => {
|
||||
if (uploadFile.status === "success") {
|
||||
const fileId = fileIds.value.filter(
|
||||
item => item.filename === uploadFile.name
|
||||
)[0]["fileId"];
|
||||
const res = await deleteFileAPI(fileId);
|
||||
if (res.code === 200) {
|
||||
message(res.msg, { type: "success" });
|
||||
return true;
|
||||
} else {
|
||||
message(res.msg, { type: "error" });
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
() => false
|
||||
);
|
||||
};
|
||||
/**部门列表 */
|
||||
const departments = ref<DepartmentInfo[]>([]);
|
||||
/**获取部门列表 */
|
||||
const getDepartments = async () => {
|
||||
const res = await getDepartmentListAPI({ page: 1, pageSize: 9999 });
|
||||
if (res.success) {
|
||||
departments.value = formatHigherOptions(
|
||||
handleTree(res.data.result, "id", "parent_id")
|
||||
);
|
||||
} else {
|
||||
departments.value = [];
|
||||
}
|
||||
};
|
||||
const formatHigherOptions = (treeList: any) => {
|
||||
// 根据返回数据的status字段值判断追加是否禁用disabled字段,返回处理后的树结构,用于上级部门级联选择器的展示(实际开发中也是如此,不可能前端需要的每个字段后端都会返回,这时需要前端自行根据后端返回的某些字段做逻辑处理)
|
||||
if (!treeList || !treeList.length) return;
|
||||
const newTreeList = [];
|
||||
for (let i = 0; i < treeList.length; i++) {
|
||||
treeList[i].disabled = treeList[i].status === 0 ? true : false;
|
||||
formatHigherOptions(treeList[i].children);
|
||||
newTreeList.push(treeList[i]);
|
||||
}
|
||||
return newTreeList;
|
||||
};
|
||||
/** 处理审核 */
|
||||
const handleAudit = async (row: CodeImportInfo) => {
|
||||
addDialog({
|
||||
title: `审核编码项`,
|
||||
props: {
|
||||
formInline: {
|
||||
way: "审核",
|
||||
description: row?.description ?? "",
|
||||
code: row?.code ?? "",
|
||||
status: row?.status ?? 3,
|
||||
user_id: row?.user_id ?? "",
|
||||
username: row?.username ?? "",
|
||||
nickname: row?.nickname ?? "",
|
||||
department_id: row?.department_id ?? "",
|
||||
department_name: row?.department_name ?? "",
|
||||
id: row?.id ?? "",
|
||||
create_time: row?.create_time ?? "",
|
||||
update_time: row?.update_time ?? ""
|
||||
}
|
||||
},
|
||||
width: "45%",
|
||||
draggable: true,
|
||||
fullscreenIcon: true,
|
||||
closeOnClickModal: false,
|
||||
|
||||
contentRenderer: () =>
|
||||
h(editForm, {
|
||||
formInline: {
|
||||
way: "审核",
|
||||
description: row?.description ?? "",
|
||||
code: row?.code ?? "",
|
||||
status: row?.status ?? 3,
|
||||
user_id: row?.user_id ?? "",
|
||||
username: row?.username ?? "",
|
||||
nickname: row?.nickname ?? "",
|
||||
department_id: row?.department_id ?? "",
|
||||
department_name: row?.department_name ?? "",
|
||||
id: row?.id ?? "",
|
||||
create_time: row?.create_time ?? "",
|
||||
update_time: row?.update_time ?? ""
|
||||
},
|
||||
ref: formRef
|
||||
}),
|
||||
|
||||
footerButtons: [
|
||||
{
|
||||
label: "取消",
|
||||
type: "info",
|
||||
btnClick: ({ dialog }) => {
|
||||
console.log("取消审核");
|
||||
closeDialog(dialog.options!, dialog.index!); // ✅ 调用封装的 `closeDialog`
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "通过",
|
||||
type: "success",
|
||||
popconfirm: {
|
||||
title: "确定要通过审核吗?",
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消"
|
||||
},
|
||||
btnClick: async ({ dialog }) => {
|
||||
const res = await putCodeImportAuditAPI({
|
||||
status: 1,
|
||||
ids: [row.id]
|
||||
});
|
||||
if (res.success) {
|
||||
closeDialog(dialog.options!, dialog.index!); // ✅ 调用封装的 `closeDialog`
|
||||
await onSearch();
|
||||
}
|
||||
message(res.msg, { type: res.success ? "success" : "error" });
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "不通过",
|
||||
type: "danger",
|
||||
popconfirm: {
|
||||
title: "确定要驳回审核吗?",
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消"
|
||||
},
|
||||
btnClick: async ({ dialog }) => {
|
||||
const res = await putCodeImportAuditAPI({
|
||||
status: 2,
|
||||
ids: [row.id]
|
||||
});
|
||||
if (res.success) {
|
||||
closeDialog(dialog.options!, dialog.index!); // ✅ 调用封装的 `closeDialog`
|
||||
await onSearch();
|
||||
}
|
||||
message(res.msg, { type: res.success ? "success" : "error" });
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
/**批量通过 */
|
||||
const onbatchAgree = async () => {
|
||||
// 返回当前选中的行
|
||||
const curSelected = tableRef.value.getTableRef().getSelectionRows();
|
||||
const res = await putCodeImportAuditAPI({
|
||||
status: 1,
|
||||
ids: getKeyList(curSelected, "id")
|
||||
});
|
||||
if (res.success) {
|
||||
message(res.msg, {
|
||||
type: "success"
|
||||
});
|
||||
tableRef.value.getTableRef().clearSelection();
|
||||
onSearch();
|
||||
} else {
|
||||
message(res.msg, { type: "error", duration: 5000 });
|
||||
}
|
||||
};
|
||||
/**批量驳回 */
|
||||
const onbatchDisagree = async () => {
|
||||
// 返回当前选中的行
|
||||
const curSelected = tableRef.value.getTableRef().getSelectionRows();
|
||||
const res = await putCodeImportAuditAPI({
|
||||
status: 2,
|
||||
ids: getKeyList(curSelected, "id")
|
||||
});
|
||||
if (res.success) {
|
||||
message(res.msg, {
|
||||
type: "success"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 页面加载执行
|
||||
*/
|
||||
onMounted(async () => {
|
||||
await onSearch();
|
||||
await getDepartments();
|
||||
});
|
||||
return {
|
||||
form,
|
||||
dataList,
|
||||
loading,
|
||||
pagination,
|
||||
columns,
|
||||
selectedNum,
|
||||
showUploadArea,
|
||||
departments,
|
||||
fileIds,
|
||||
fileList,
|
||||
uploadStatus,
|
||||
beforeUpload,
|
||||
handleUpload,
|
||||
beforeRemove,
|
||||
openDialog,
|
||||
onSearch,
|
||||
resetForm,
|
||||
handleDelete,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
handleSelectionChange,
|
||||
onSelectionCancel,
|
||||
onbatchDel,
|
||||
onDownloadTemplate,
|
||||
handleAudit,
|
||||
onbatchDisagree,
|
||||
onbatchAgree
|
||||
};
|
||||
};
|
@ -6,12 +6,28 @@
|
||||
:model="form"
|
||||
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]"
|
||||
>
|
||||
<el-form-item label="用户账号" prop="usename">
|
||||
<el-input
|
||||
v-model="form.username"
|
||||
placeholder="请输入用户账号~"
|
||||
clearable
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名称" prop="nickname">
|
||||
<el-input
|
||||
v-model="form.nickname"
|
||||
placeholder="请输入用户昵称~"
|
||||
clearable
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="编码" prop="code">
|
||||
<el-input
|
||||
v-model="form.code"
|
||||
placeholder="请输入编码"
|
||||
clearable
|
||||
class="!w-[180px]"
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="编码描述" prop="description">
|
||||
@ -19,7 +35,44 @@
|
||||
v-model="form.description"
|
||||
clearable
|
||||
placeholder="请输入编码描述~"
|
||||
class="!w-[180px]"
|
||||
class="!w-[200px]"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="hasAuth('code:data:importAdmin')"
|
||||
label="所属部门:"
|
||||
prop="department_id"
|
||||
>
|
||||
<el-cascader
|
||||
v-model="form.department_id"
|
||||
class="!w-[200px]"
|
||||
:options="departments"
|
||||
:props="{
|
||||
value: 'id',
|
||||
label: 'name',
|
||||
emitPath: false,
|
||||
checkStrictly: true
|
||||
}"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择所属部门~"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span>{{ data.name }}</span>
|
||||
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
||||
</template>
|
||||
</el-cascader>
|
||||
</el-form-item>
|
||||
<el-form-item label="导入时间" prop="timeRange">
|
||||
<el-date-picker
|
||||
v-model="form.timeRange"
|
||||
:shortcuts="getPickerShortcuts()"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期时间"
|
||||
end-placeholder="结束日期时间"
|
||||
value-format="x"
|
||||
unlink-panels
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
@ -36,7 +89,7 @@
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<PureTableBar title="编码管理" :columns="columns" @refresh="onSearch">
|
||||
<PureTableBar title="数据维护" :columns="columns" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button
|
||||
v-if="hasAuth('code:btn:add')"
|
||||
@ -200,10 +253,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: "CodeAdmin"
|
||||
name: "DataMaintain"
|
||||
});
|
||||
import { ref } from "vue";
|
||||
import { useCode } from "./utils/hook";
|
||||
import { getPickerShortcuts } from "@/views/monitor/utils";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { PureTableBar } from "@/components/RePureTableBar";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
@ -227,8 +281,8 @@ const {
|
||||
pagination,
|
||||
columns,
|
||||
selectedNum,
|
||||
departments,
|
||||
showUploadArea,
|
||||
fileIds,
|
||||
fileList,
|
||||
uploadStatus,
|
||||
beforeUpload,
|
@ -14,13 +14,15 @@ import {
|
||||
postAddCodeAPI,
|
||||
putUpdateCodeAPI
|
||||
} from "@/api/code";
|
||||
import { getKeyList } from "@pureadmin/utils";
|
||||
import { getKeyList, handleTree } from "@pureadmin/utils";
|
||||
import {
|
||||
ElMessageBox,
|
||||
type UploadProps,
|
||||
type UploadUserFile
|
||||
} from "element-plus";
|
||||
import { deleteFileAPI, postUploadFileAPI } from "@/api/file";
|
||||
import type { DepartmentInfo } from "types/system";
|
||||
import { getDepartmentListAPI } from "@/api/system";
|
||||
|
||||
export const useCode = (tableRef: Ref) => {
|
||||
/**
|
||||
@ -28,7 +30,11 @@ export const useCode = (tableRef: Ref) => {
|
||||
*/
|
||||
const form = reactive({
|
||||
code: "",
|
||||
description: ""
|
||||
description: "",
|
||||
username: "",
|
||||
department_id: "",
|
||||
timeRange: [null, null],
|
||||
nickname: ""
|
||||
});
|
||||
/**
|
||||
* 表单Ref
|
||||
@ -74,6 +80,21 @@ export const useCode = (tableRef: Ref) => {
|
||||
fixed: "left",
|
||||
reserveSelection: true // 数据刷新后保留选项
|
||||
},
|
||||
{
|
||||
label: "用户账号",
|
||||
prop: "username",
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
label: "用户昵称",
|
||||
prop: "nickname",
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
label: "所属部门",
|
||||
prop: "department_name",
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
label: "编码",
|
||||
prop: "code",
|
||||
@ -105,7 +126,12 @@ export const useCode = (tableRef: Ref) => {
|
||||
page: pagination.currentPage,
|
||||
pageSize: pagination.pageSize,
|
||||
description: form.description,
|
||||
code: form.code
|
||||
code: form.code,
|
||||
department_id: form.department_id,
|
||||
nickname: form.nickname,
|
||||
username: form.username,
|
||||
startTime: form.timeRange[0] ? form.timeRange[0] : null,
|
||||
endTime: form.timeRange[1] ? form.timeRange[1] : null
|
||||
});
|
||||
if (res.success) {
|
||||
dataList.value = res.data.result;
|
||||
@ -149,7 +175,12 @@ export const useCode = (tableRef: Ref) => {
|
||||
page: pagination.currentPage,
|
||||
pageSize: val,
|
||||
description: form.description,
|
||||
code: form.code
|
||||
code: form.code,
|
||||
department_id: form.department_id,
|
||||
nickname: form.nickname,
|
||||
username: form.username,
|
||||
startTime: form.timeRange[0] ? form.timeRange[0] : null,
|
||||
endTime: form.timeRange[1] ? form.timeRange[1] : null
|
||||
});
|
||||
if (res.success) {
|
||||
dataList.value = res.data.result;
|
||||
@ -171,7 +202,12 @@ export const useCode = (tableRef: Ref) => {
|
||||
page: val,
|
||||
pageSize: pagination.pageSize,
|
||||
description: form.description,
|
||||
code: form.code
|
||||
code: form.code,
|
||||
department_id: form.department_id,
|
||||
nickname: form.nickname,
|
||||
username: form.username,
|
||||
startTime: form.timeRange[0] ? form.timeRange[0] : null,
|
||||
endTime: form.timeRange[1] ? form.timeRange[1] : null
|
||||
});
|
||||
if (res.code === 200) {
|
||||
dataList.value = res.data.result;
|
||||
@ -371,12 +407,37 @@ export const useCode = (tableRef: Ref) => {
|
||||
() => false
|
||||
);
|
||||
};
|
||||
/**部门列表 */
|
||||
const departments = ref<DepartmentInfo[]>([]);
|
||||
/**获取部门列表 */
|
||||
const getDepartments = async () => {
|
||||
const res = await getDepartmentListAPI({ page: 1, pageSize: 9999 });
|
||||
if (res.success) {
|
||||
departments.value = formatHigherOptions(
|
||||
handleTree(res.data.result, "id", "parent_id")
|
||||
);
|
||||
} else {
|
||||
departments.value = [];
|
||||
}
|
||||
};
|
||||
const formatHigherOptions = (treeList: any) => {
|
||||
// 根据返回数据的status字段值判断追加是否禁用disabled字段,返回处理后的树结构,用于上级部门级联选择器的展示(实际开发中也是如此,不可能前端需要的每个字段后端都会返回,这时需要前端自行根据后端返回的某些字段做逻辑处理)
|
||||
if (!treeList || !treeList.length) return;
|
||||
const newTreeList = [];
|
||||
for (let i = 0; i < treeList.length; i++) {
|
||||
treeList[i].disabled = treeList[i].status === 0 ? true : false;
|
||||
formatHigherOptions(treeList[i].children);
|
||||
newTreeList.push(treeList[i]);
|
||||
}
|
||||
return newTreeList;
|
||||
};
|
||||
|
||||
/**
|
||||
* 页面加载执行
|
||||
*/
|
||||
onMounted(async () => {
|
||||
await onSearch();
|
||||
await getDepartments();
|
||||
});
|
||||
return {
|
||||
form,
|
||||
@ -385,6 +446,7 @@ export const useCode = (tableRef: Ref) => {
|
||||
pagination,
|
||||
columns,
|
||||
selectedNum,
|
||||
departments,
|
||||
showUploadArea,
|
||||
fileIds,
|
||||
fileList,
|
68
types/code.d.ts
vendored
68
types/code.d.ts
vendored
@ -6,6 +6,16 @@ export interface CodeInfo {
|
||||
code: string;
|
||||
/** 编码描述 */
|
||||
description: string;
|
||||
/**用户ID */
|
||||
user_id: string;
|
||||
/**用户昵称 */
|
||||
nickname: string;
|
||||
/**用户账号 */
|
||||
username: string;
|
||||
/**部门ID */
|
||||
department_id: string;
|
||||
/**部门名称 */
|
||||
department_name: string;
|
||||
/** 创建时间 */
|
||||
create_time: string;
|
||||
/** 更新时间 */
|
||||
@ -88,3 +98,61 @@ export interface QueryCodeLogInfo {
|
||||
/** 部门名称 */
|
||||
department_name: string;
|
||||
}
|
||||
|
||||
/**编码反馈信息 */
|
||||
export interface CodeFeedbackInfo {
|
||||
/**反馈ID */
|
||||
id: string;
|
||||
/**编码ID */
|
||||
code_id: string;
|
||||
/**编码 */
|
||||
code: string;
|
||||
/**编码描述 */
|
||||
description: string;
|
||||
/**反馈编码 */
|
||||
feedback_code: string;
|
||||
/**反馈文本 */
|
||||
feedback_description: string;
|
||||
/** 创建时间 */
|
||||
create_time: string;
|
||||
/** 更新时间 */
|
||||
update_time: string;
|
||||
/**用户ID */
|
||||
user_id: string;
|
||||
/**用户昵称 */
|
||||
nickname: string;
|
||||
/**用户账号 */
|
||||
username: string;
|
||||
/**部门ID */
|
||||
department_id: string;
|
||||
/**部门名称 */
|
||||
department_name: string;
|
||||
/**审核状态 */
|
||||
status: number;
|
||||
}
|
||||
|
||||
/**编码导入信息 */
|
||||
export interface CodeImportInfo {
|
||||
/**导入ID */
|
||||
id: string;
|
||||
/**导入状态 */
|
||||
status: number;
|
||||
/**编码 */
|
||||
code: string;
|
||||
/**编码描述 */
|
||||
description: string;
|
||||
/** 创建时间 */
|
||||
create_time: string;
|
||||
/** 更新时间 */
|
||||
update_time: string;
|
||||
/**用户ID */
|
||||
user_id: string;
|
||||
/**用户昵称 */
|
||||
nickname: string;
|
||||
/**用户账号 */
|
||||
username: string;
|
||||
/**部门ID */
|
||||
department_id: string;
|
||||
/**部门名称 */
|
||||
department_name: string;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user