编写新页面,添加评级审核处理页面

This commit is contained in:
wcq 2023-08-25 16:27:27 +08:00
parent 7395840462
commit 7aec520aa5
40 changed files with 1595 additions and 385 deletions

View File

@ -2,7 +2,7 @@
VITE_PORT = 8848
# 开发环境读取配置文件路径
VITE_PUBLIC_PATH = /wd-smebiz-manage-web/
VITE_PUBLIC_PATH = /wd-smebiz-manage-web-v2/
# 开发环境路由历史模式Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数"
VITE_ROUTER_HISTORY = "hash"

View File

@ -1,5 +1,5 @@
# 线上环境平台打包路径
VITE_PUBLIC_PATH = /wd-smebiz-manage-web/
VITE_PUBLIC_PATH = /wd-smebiz-manage-web-v2/
# 线上环境路由历史模式Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数"
VITE_ROUTER_HISTORY = "hash"

2
.gitignore vendored
View File

@ -19,5 +19,5 @@ tests/**/coverage/
*.njsproj
*.sln
tsconfig.tsbuildinfo
/wd-smebiz-manage-web/
/wd-smebiz-manage-web-v2/
/yd-admin/

View File

@ -9,7 +9,7 @@
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0"
/>
<title>评级系统</title>
<link rel="icon" href="/favicon.ico" />
<link rel="icon" href="/favicon2.ico" />
<script>
window.process = {};
</script>

View File

@ -1,5 +1,5 @@
{
"name": "wd-smebiz-manage-web",
"name": "wd-smebiz-manage-web-v2",
"version": "4.5.0",
"private": true,
"scripts": {

BIN
public/favicon2.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
public/logo2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
src/assets/login/logo2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -23,21 +23,23 @@
type="primary"
v-if="fileMd && props.showDownload === true"
@click="fileDownload"
>下载</el-button
>下载
</el-button
>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { ElMessage, genFileId, UploadFile, UploadFiles } from "element-plus";
import type { UploadInstance, UploadProps, UploadRawFile } from "element-plus";
import { getToken } from "@/utils/auth";
import { api } from "@/api/api";
import {computed, onMounted, ref} from "vue";
import {ElMessage, genFileId, UploadFile, UploadFiles} from "element-plus";
import type {UploadInstance, UploadProps, UploadRawFile} from "element-plus";
import {getToken} from "@/utils/auth";
import {api} from "@/api/api";
const props = defineProps<{ modelValue: string; showDownload?: boolean }>();
const emit = defineEmits(["update:modelValue"]);
const headers = ref({ Authorization: "" });
const headers = ref({Authorization: ""});
const upload = ref<UploadInstance>();
const fileMd = computed({
get() {
@ -50,7 +52,7 @@ const fileMd = computed({
});
const fileDownload = () => {
api
.post("/wd-smebiz/smebiz_rate/form_file/get", { md: fileMd.value })
.post("/wd-smebiz/smebiz_rate/form_file/get", {md: fileMd.value})
.then(res => {
let fileUrl = res.data.file_url;
ElMessage.success("开始下载");
@ -93,4 +95,7 @@ onMounted(() => {
headers.value.Authorization = "Bearer " + getToken().accessToken;
});
defineExpose({
upload
})
</script>

View File

@ -37,7 +37,7 @@ nextTick(() => {
class="horizontal-header"
>
<div class="horizontal-header-left" @click="backTopMenu">
<img src="/logo.png" alt="logo" />
<img src="/logo2.png" alt="logo" />
<span>{{ title }}</span>
</div>
<el-menu

View File

@ -19,7 +19,7 @@ const { title } = useNav();
class="sidebar-logo-link"
:to="getTopMenu()?.path ?? '/'"
>
<img src="/logo.png" alt="logo" />
<img src="/logo2.png" alt="logo" />
<span class="sidebar-title">{{ title }}</span>
</router-link>
<router-link
@ -29,7 +29,7 @@ const { title } = useNav();
class="sidebar-logo-link"
:to="getTopMenu()?.path ?? '/'"
>
<img src="/logo.png" alt="logo" />
<img src="/logo2.png" alt="logo" />
<span class="sidebar-title">{{ title }}</span>
</router-link>
</transition>

View File

@ -5,7 +5,7 @@ export const routerArrays: Array<RouteConfigs> =
VITE_HIDE_HOME === "false"
? [
{
path: "/welcome",
path: "/dashboard",
meta: {
title: "首页",
icon: "homeFilled"

View File

@ -1,9 +1,9 @@
// import "@/utils/sso";
import { getConfig } from "@/config";
import {getConfig} from "@/config";
import NProgress from "@/utils/progress";
import { sessionKey, type DataInfo } from "@/utils/auth";
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
import { usePermissionStoreHook } from "@/store/modules/permission";
import {sessionKey, type DataInfo} from "@/utils/auth";
import {useMultiTagsStoreHook} from "@/store/modules/multiTags";
import {usePermissionStoreHook} from "@/store/modules/permission";
import {
Router,
createRouter,
@ -21,7 +21,7 @@ import {
formatTwoStageRoutes,
formatFlatteningRoutes
} from "./utils";
import { buildHierarchyTree } from "@/utils/tree";
import {buildHierarchyTree} from "@/utils/tree";
import {isUrl, openLink, isAllEmpty, storageLocal} from "@pureadmin/utils";
import remainingRouter from "./modules/remaining";
@ -31,7 +31,13 @@ import remainingRouter from "./modules/remaining";
* https://cn.vitejs.dev/guide/features.html#negative-patterns
*/
const modules: Record<string, any> = import.meta.glob(
["./modules/**/*.ts", "!./modules/**/remaining.ts","!./modules/test.ts","!./modules/companyDataManage.ts"],
["./modules/**/*.ts", "!./modules/**/remaining.ts",
// "!./modules/test.ts",
// "!./modules/rateApplyManage.ts",
"!./modules/companyDataManage.ts",
"!./modules/rateManage.ts",
],
{
eager: true
}
@ -72,7 +78,7 @@ export const router: Router = createRouter({
if (from.meta.saveSrollTop) {
const top: number =
document.documentElement.scrollTop || document.body.scrollTop;
resolve({ left: 0, top });
resolve({left: 0, top});
}
}
});
@ -82,7 +88,7 @@ export const router: Router = createRouter({
/** 重置路由 */
export function resetRouter() {
router.getRoutes().forEach(route => {
const { name, meta } = route;
const {name, meta} = route;
if (name && router.hasRoute(name) && meta?.backstage) {
router.removeRoute(name);
router.options.routes = formatTwoStageRoutes(
@ -98,7 +104,7 @@ export function resetRouter() {
/** 路由白名单 */
const whiteList = ["/login"];
const { VITE_HIDE_HOME } = import.meta.env;
const {VITE_HIDE_HOME} = import.meta.env;
router.beforeEach((to: ToRouteType, _from, next) => {
if (to.meta?.keepAlive) {
@ -118,18 +124,20 @@ router.beforeEach((to: ToRouteType, _from, next) => {
else document.title = item.meta.title as string;
});
}
/** 如果已经登录并存在登录信息后不能跳转到路由白名单,而是继续保持在当前页面 */
function toCorrectRoute() {
whiteList.includes(to.fullPath) ? next(_from.fullPath) : next();
}
if (userInfo) {
// 无权限跳转403页面
if (to.meta?.roles && !isOneOfArray(to.meta?.roles, userInfo?.roles)) {
next({ path: "/error/403" });
next({path: "/error/403"});
}
// 开启隐藏首页后在浏览器地址栏手动输入首页welcome路由则跳转到404页面
if (VITE_HIDE_HOME === "true" && to.fullPath === "/welcome") {
next({ path: "/error/404" });
next({path: "/error/404"});
}
if (_from?.name) {
// name为超链接
@ -146,7 +154,7 @@ router.beforeEach((to: ToRouteType, _from, next) => {
) {
initRouter().then((router: Router) => {
if (!useMultiTagsStoreHook().getMultiTagsCache) {
const { path } = to;
const {path} = to;
const route = findRouteByPath(
path,
router.options.routes[0].children
@ -156,14 +164,14 @@ router.beforeEach((to: ToRouteType, _from, next) => {
if (route && route.meta?.title) {
if (isAllEmpty(route.parentId) && route.meta?.backstage) {
// 此处为动态顶级路由(目录)
const { path, name, meta } = route.children[0];
const {path, name, meta} = route.children[0];
useMultiTagsStoreHook().handleTags("push", {
path,
name,
meta
});
} else {
const { path, name, meta } = route;
const {path, name, meta} = route;
useMultiTagsStoreHook().handleTags("push", {
path,
name,
@ -183,7 +191,7 @@ router.beforeEach((to: ToRouteType, _from, next) => {
if (whiteList.indexOf(to.path) !== -1) {
next();
} else {
next({ path: "/login" });
next({path: "/login"});
}
} else {
next();

View File

@ -9,6 +9,7 @@ import { GridComponent } from 'echarts/components';
import { LineChart } from 'echarts/charts';
import { UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
import {useDark} from "@pureadmin/utils";
echarts.use([GridComponent, LineChart, CanvasRenderer, UniversalTransition]);
@ -33,7 +34,7 @@ const chartOption = ref(
xAxis: [
{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
data: ['23/8/12', '23/8/13', '23/8/14', '23/8/15', '23/8/16', '23/8/17', '23/8/18'],
axisTick: {
alignWithLabel: true
}
@ -76,11 +77,21 @@ const elId = ref('apply_bar_' + Date.now())
onBeforeMount(() => {
})
const isDark = useDark()
watch(() => isDark.isDark.value, (value: boolean) => {
if (chartObj.chart) {
chartObj.chart.dispose();
chartObj.chart = echarts.init(document.getElementById(elId.value), value ? 'dark' : 'light'); //init'light'/'dark'
chartObj.chart.setOption(chartOption.value);
props.data && chartObj.chart?.setOption(dataToOptionsData(props.data));
}
})
onMounted(() => {
elId.value = 'apply_bar_' + Date.now() + Math.random()
nextTick(() => {
const chartDom = document.getElementById(elId.value)!;
chartObj.chart = echarts.init(chartDom, 'dark')
chartObj.chart = echarts.init(chartDom, isDark.isDark.value ? 'dark' : 'light')
chartObj.chartDom = chartDom
chartObj.chart?.setOption(chartOption.value)
window.addEventListener('resize', () => {
@ -88,20 +99,18 @@ onMounted(() => {
})
})
})
const dataToOptionsData = (data) => {
return {
xAxis: [{data: data.map(item => item[0])}],
series: [{data: data.map(item => item[1])}]
}
}
watch(() => props.data, (newVal) => {
console.log({
xAxis: [{data: newVal.map(item => item[0])}],
series: [{data: newVal.map(item => item[1])}]
})
newVal && chartObj.chart?.setOption({
xAxis: [{data: newVal.map(item => item[0])}],
series: [{data: newVal.map(item => item[1])}]
});
newVal && chartObj.chart?.setOption(dataToOptionsData(newVal));
}, {
immediate: true
})
</script>

View File

@ -50,15 +50,15 @@ const chartOption = ref(
},
series: [
{
name: 'Access From',
name: '等级',
type: 'pie',
radius: '80%',
data: [
{value: 1048, name: 'Search Engine'},
{value: 735, name: 'Direct'},
{value: 580, name: 'Email'},
{value: 484, name: 'Union Ads'},
{value: 300, name: 'Video Ads'}
{value: 1048, name: 'C'},
{value: 735, name: 'B'},
{value: 580, name: 'A'},
{value: 484, name: 'AA'},
{value: 300, name: 'AAA'}
],
emphasis: {
itemStyle: {
@ -75,7 +75,7 @@ const chartOption = ref(
type ChartData = [string, number][]
const data = ref<ChartData>()
const props = withDefaults(defineProps<{ data: ChartData }>(), {
data: () => []
data: () => [['AAA', 300], ['AA', 484], ['A', 580], ['B', 735], ['C', 1048]]
});
const chartObj: {
chartDom: HTMLElement,
@ -89,9 +89,15 @@ onBeforeMount(() => {
})
const isDark = useDark()
watch(()=>isDark.isDark.value,(value:boolean)=>{
watch(() => isDark.isDark.value, (value: boolean) => {
if (chartObj.chart) {
chartObj.chart.dispose();
chartObj.chart = echarts.init(document.getElementById(elId.value), value ? 'dark' : 'light'); //init'light'/'dark'
chartObj.chart.setOption(chartOption.value);
props.data && chartObj.chart?.setOption(dataToOptionsData(props.data));
}
})
onMounted(() => {
elId.value = 'rate_level_pie_' + Date.now() + Math.random()
nextTick(() => {
@ -104,14 +110,14 @@ onMounted(() => {
})
})
})
const dataToOptionsData = (data) => {
return {
series: [{data: data.map(item => ({name: item[0], value: item[1]}))}]
}
}
watch(() => props.data, (newVal) => {
console.log({
xAxis: [{data: newVal.map(item => item[0])}],
series: [{data: newVal.map(item => item[1])}]
})
newVal && chartObj.chart?.setOption({
series: [{data: newVal.map(item => ({name: item[0], value: item[1]}))}]
});
newVal && chartObj.chart?.setOption(dataToOptionsData(newVal));
}, {
immediate: true
})

View File

@ -117,7 +117,7 @@ onBeforeUnmount(() => {
<div class="login-box">
<div class="login-form">
<div class="avatar flex-c">
<img src="@/assets/login/logo.png" alt=""/>
<img src="@/assets/login/logo2.png" alt=""/>
</div>
<!-- <avatar class="avatar" />-->
<Motion>

View File

@ -6,52 +6,70 @@
<div class="rate-serve-info__items">
<div>
<span>受评主体</span>
<span>{{ rateServe.company?.name }}</span>
<span>{{ rateServe.company?.name || '-' }}</span>
</div>
<div>
<span>申请时间</span>
<span>{{ rateServe.create_time }}</span>
<span>{{ rateServe.create_time || '-' }}</span>
</div>
<div>
<span>服务编号</span>
<span>{{ rateServe.serve_id }}</span>
<span>{{ rateServe.serve_id || '-' }}</span>
</div>
<div>
<span>完成时间</span>
<span>{{ rateServe.finish_time }}</span>
<span>{{ rateServe.finish_time || '-' }}</span>
</div>
</div>
<el-text type="primary" class="rate-serve-state">
{{ '审核中' }}
<el-text :type="RateServeStateLevelDic[rateServe.status]" class="rate-serve-state">
{{ RateServeStateNameDic[rateServe.status] }}
</el-text>
</div>
<el-divider style="margin-top: 0.5rem; margin-bottom: 0.5rem"></el-divider>
<div class="node-item">
<div class="node-title">
<span>1.企业提交材料审核</span>
<el-text type="success" class="!mx-2 !text-[1rem]">{{ '已完成' }}</el-text>
<el-text :type="NodeStateLevelDic[rateServe.rate_post_data_check_node?.status]"
class="node-state-text">
{{ NodeStateNameDic[rateServe.rate_post_data_check_node?.status] }}
</el-text>
</div>
<div class="node-content">
<table class="w-full fill-sheet-node-table" style="table-layout: fixed;">
<tr>
<th><span>填报数据</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline">导入</el-button>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline"
@click="showFillSheetUpload">导入
</el-button>
</th>
<th><span>备注</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline">编辑</el-button>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline"
@click="showRemarkEdit('rate_post_data_check_node')">编辑
</el-button>
</th>
<th>操作
</th>
</tr>
<tr>
<td>
<el-button type="success" size="small">原件</el-button>
<el-button type="success" size="small" @click="showOriginFillSheet">原件</el-button>
<el-button type="primary" size="small">审核</el-button>
</td>
<td>
数据缺失字段数据缺失
-
</td>
<td>
<el-button type="primary" size="small">通过</el-button>
<el-popconfirm
width="220"
confirm-button-text="确定"
cancel-button-text="取消"
icon-color="#626AEF"
title="确认通过?"
>
<template #reference>
<el-button type="primary" size="small">通过</el-button>
</template>
</el-popconfirm>
</td>
</tr>
</table>
@ -60,16 +78,31 @@
<div class="node-item">
<div class="node-title">
<span>2.三方接口数据审核</span>
<el-text type="success" class="!mx-2 !text-[1rem]">{{ '已完成' }}</el-text>
<el-text :type="NodeStateLevelDic[rateServe.rate_data_preparation_node?.status]"
class="node-state-text">
{{ NodeStateNameDic[rateServe.rate_data_preparation_node?.status] }}
</el-text>
</div>
<div class="node-content">
<table class="w-full fill-sheet-node-table" style="table-layout: fixed;">
<tr>
<th><span>接口数据</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline">导入</el-button>
<el-popconfirm
width="220"
confirm-button-text="确定"
cancel-button-text="取消"
title="导入三方接口数据?"
>
<template #reference>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline">导入</el-button>
</template>
</el-popconfirm>
</th>
<th><span>备注</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline">编辑</el-button>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline"
@click="showRemarkEdit('rate_data_preparation_node')">编辑
</el-button>
</th>
<th>操作
</th>
@ -79,10 +112,20 @@
<el-button type="primary" size="small">审核</el-button>
</td>
<td>
数据缺失字段数据缺失
-
</td>
<td>
<el-button type="primary" size="small">通过</el-button>
<el-popconfirm
width="220"
confirm-button-text="确定"
cancel-button-text="取消"
icon-color="#626AEF"
title="确认通过?"
>
<template #reference>
<el-button type="primary" size="small">通过</el-button>
</template>
</el-popconfirm>
</td>
</tr>
</table>
@ -91,13 +134,14 @@
<div class="node-item">
<div class="node-title">
<span>3.费用到账检查</span>
<el-text type="success" class="!mx-2 !text-[1rem]">{{ '已完成' }}</el-text>
<el-text type="warning" class="node-state-text">{{ '未完成' }}</el-text>
</div>
<div class="node-content">
<table class="w-full fill-sheet-node-table" style="table-layout: fixed;">
<tr>
<th><span>接口数据</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline">导入</el-button>
<th>
<span class="inline-block" style="width: 4rem">应收款</span>
<span class="inline-block" style="width: 4rem">实收款</span>
</th>
<th><span>备注</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline">编辑</el-button>
@ -107,13 +151,24 @@
</tr>
<tr>
<td>
<el-button type="primary" size="small">审核</el-button>
<span class="inline-block" style="width: 4rem">-</span>
<span class="inline-block" style="width: 4rem">-</span>
</td>
<td>
数据缺失字段数据缺失
-
</td>
<td>
<el-button type="primary" size="small">通过</el-button>
<el-popconfirm
width="220"
confirm-button-text="确定"
cancel-button-text="取消"
icon-color="#626AEF"
title="确认通过?"
>
<template #reference>
<el-button type="primary" size="small">通过</el-button>
</template>
</el-popconfirm>
</td>
</tr>
</table>
@ -122,25 +177,160 @@
</div>
<div class="flex">
<div class="ml-auto mx-4 my-2">
<el-button size="small" type="warning">取消作业</el-button>
<el-button size="small" type="danger">删除</el-button>
<el-button size="small" type="primary">完成作业</el-button>
<el-button size="small" type="warning" @click="cancelWork">取消</el-button>
<el-button size="small" type="danger" @click="deleteWork">删除</el-button>
<el-button size="small" type="primary" @click="finishWork">完成审核</el-button>
</div>
</div>
<el-dialog style="width: 32rem" title="企业材料审核" center v-model="cancelWorkVisible" append-to-body>
<div class="m-2">状态明细</div>
<el-input type="textarea" :rows="6" v-model="cancelRemark" placeholder="请输入审核不通过原因"></el-input>
<template #footer>
<div class="flex">
<div class="ml-auto">
<el-button type="info" size="small" @click="cancelWorkVisible=false">取消</el-button>
<el-button type="primary" size="small" @click="confirmCancelWork">确定</el-button>
</div>
</div>
</template>
</el-dialog>
<el-dialog style="width: 32rem" title="删除作业" center v-model="deleteWorkVisible" append-to-body>
<div class="m-2">状态明细</div>
<el-input type="textarea" :rows="6" v-model="deleteRemark" placeholder="请输入备注"></el-input>
<template #footer>
<div class="flex">
<div class="ml-auto">
<el-button type="info" size="small" @click="deleteWorkVisible=false">取消</el-button>
<el-button type="primary" size="small" @click="confirmDeleteWork">确定</el-button>
</div>
</div>
</template>
</el-dialog>
<el-dialog style="width: 32rem" title="完成作业" center v-model="finishWorkVisible" append-to-body>
<div class="m-2">状态明细</div>
<el-input type="textarea" :rows="6" v-model="finishRemark" placeholder="请输入审核通过备注"></el-input>
<template #footer>
<div class="flex">
<div class="ml-auto">
<el-button type="info" size="small" @click="finishWorkVisible=false">取消</el-button>
<el-button type="primary" size="small" @click="confirmFinishWork">确定</el-button>
</div>
</div>
</template>
</el-dialog>
<el-dialog style="width: 30rem" title="企业填报文件导入" v-model="fillSheetUploadVisible">
<file-upload-md v-model="rateServe.rate_post_data_check_node.file_id"
ref="fillSheetUploadRef"></file-upload-md>
<template #footer>
<div class="flex">
<div class="ml-auto">
<el-button type="info" size="small" @click="fillSheetUploadVisible=false">取消</el-button>
<el-button type="primary" size="small" @click="confirmFillSheetUpload">确定</el-button>
</div>
</div>
</template>
</el-dialog>
<el-dialog title="编辑备注" style="width: 32rem" center v-model="nodeRemarkEditVisible">
<div class="m-2">备注信息</div>
<el-input type="textarea" :rows="6" v-model="editRemarkNodeTemp.remark" placeholder="请输入备注信息"></el-input>
<template #footer>
<div class="flex">
<div class="ml-auto">
<el-button type="info" size="small" @click="nodeRemarkEditVisible=false">取消</el-button>
<el-button type="primary" size="small" @click="confirmNodeRemarkEdit">确定</el-button>
</div>
</div>
</template>
</el-dialog>
</div>
</el-card>
</template>
<script setup lang="ts">
import {RateServe} from "@/views/smebiz/types";
import {
NodeStateLevelDic,
NodeStateNameDic,
RateServeStateLevelDic,
RateServeStateNameDic
} from "@/views/smebiz/config";
import {ref} from "vue";
import {ElMessage} from "element-plus";
import FileUploadMd from "@/components/EditTabel/fileUploadMd.vue";
const prop = defineProps<{ rateServe: RateServe }>()
const cancelWorkVisible = ref(false)
const deleteWorkVisible = ref(false)
const finishWorkVisible = ref(false)
const cancelRemark = ref('资料审核不通过')
const deleteRemark = ref('取消该作业')
const finishRemark = ref('资料审核通过')
const editRemarkNodeTemp = ref({
nodeName: '',
remark: ''
})
const nodeRemarkEditVisible = ref(false)
const fillSheetUploadVisible = ref(false)
const fillSheetUploadRef = ref(null)
const showFillSheetUpload = () => {
fillSheetUploadVisible.value = true
}
const confirmFillSheetUpload = () => {
fillSheetUploadVisible.value = false
}
const cancelWork = () => {
cancelWorkVisible.value = true
}
const confirmCancelWork = () => {
cancelWorkVisible.value = false
ElMessage.success("已取消审核")
}
const deleteWork = () => {
deleteWorkVisible.value = true
}
const confirmDeleteWork = () => {
deleteWorkVisible.value = false
ElMessage.success("已删除")
}
const finishWork = () => {
finishWorkVisible.value = true
}
const confirmFinishWork = () => {
finishWorkVisible.value = false
ElMessage.success("已通过审核")
}
const showRemarkEdit = (nodeName) => {
editRemarkNodeTemp.value = {
nodeName: nodeName,
remark: prop.rateServe[nodeName]?.remark
}
nodeRemarkEditVisible.value = true
}
const confirmNodeRemarkEdit = () => {
nodeRemarkEditVisible.value = false
ElMessage.success("保存成功")
}
const showOriginFillSheet=()=>{
window.open('https://view.officeapps.live.com/op/view.aspx?src=newteach.pbworks.com%2Ff%2Fele%2Bnewsletter.docx','_blank')
}
</script>
<style lang="scss">
.rate-workflow {
height: 100%;
overflow-y: auto;
border: 1px dashed;
//border: 1px dashed;
font-size: 1rem;
.el-card__body {
height: 100%;
}
@ -149,10 +339,9 @@ const prop = defineProps<{ rateServe: RateServe }>()
<style scoped lang="scss">
.rate-serve-info {
padding: 1rem;
border-bottom: 1px dashed;
//border-bottom: 1px dashed;
}
.rate-serve-state {
@ -188,11 +377,19 @@ const prop = defineProps<{ rateServe: RateServe }>()
}
.node-title {
@apply my-2
@apply flex my-2 w-52
}
.node-state-text {
margin-left: auto !important; /* 8px */
;
margin-right: 0.5rem !important /* 8px */
;
font-size: 1rem !important;
}
.node-content {
border: 1px dashed;
@apply pt-4 pb-6 border
border: 1px dashed var(--el-border-color);
@apply pt-4 pb-6
}
</style>

View File

@ -0,0 +1,458 @@
<template>
<el-card class="rate-workflow" style="color: var(--el-text-color-regular)">
<div class="flex flex-col h-full">
<div class="flex-1">
<div class="rate-serve-info flex">
<div class="rate-serve-info__items">
<div>
<span>受评主体</span>
<span>{{ rateServe.company?.name || '-' }}</span>
</div>
<div>
<span>申请时间</span>
<span>{{ rateServe.create_time || '-' }}</span>
</div>
<div>
<span>服务编号</span>
<span>{{ rateServe.serve_id || '-' }}</span>
</div>
<div>
<span>完成时间</span>
<span>{{ rateServe.finish_time || '-' }}</span>
</div>
</div>
<el-text :type="RateServeStateLevelDic[rateServe.status]" class="rate-serve-state">
{{ RateServeStateNameDic[rateServe.status] }}
</el-text>
</div>
<el-divider style="margin-top: 0.5rem; margin-bottom: 0.5rem"></el-divider>
<div class="node-item">
<div class="node-title">
<span>1.评级打分业务</span>
<el-text :type="NodeStateLevelDic[rateServe.rate_work_node?.status]"
class="node-state-text">
{{ NodeStateNameDic[rateServe.rate_work_node?.status] }}
</el-text>
</div>
<div class="node-content">
<table class="w-full fill-sheet-node-table" style="table-layout: fixed;">
<tr>
<th><span>等级</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline">打分</el-button>
</th>
<th><span>分数</span></th>
<th><span>打分时间</span></th>
<th><span>打分详情</span></th>
<th><span>有效期</span></th>
<th colspan="2"><span>备注</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline"
@click="showRemarkEdit('rate_work_node')">编辑
</el-button>
</th>
<th>操作
</th>
</tr>
<tr>
<td class="font-bold text-2xl">
{{ rateServe.rate_work_node?.rank || '-' }}
</td>
<td class="font-bold text-2xl">
{{ rateServe.rate_work_node?.scope ? `${rateServe.rate_work_node?.scope}/100` : '-' }}
</td>
<td>{{ rateServe.rate_work_node?.rate_time || '-' }}</td>
<td>
<el-button type="primary" size="small">查看</el-button>
</td>
<td>1</td>
<td colspan="2">{{ rateServe.rate_work_node?.remark || '-' }}</td>
<td>
<el-popconfirm
width="220"
icon-color="#626AEF"
confirm-button-text="确定"
cancel-button-text="取消"
title="确认通过?"
>
<template #reference>
<el-button type="primary" size="small">通过</el-button>
</template>
</el-popconfirm>
<el-popconfirm
width="220"
:icon="WarningFilled as any"
:icon-color="'red'"
confirm-button-text="确定"
cancel-button-text="取消"
title="确认重置?"
>
<template #reference>
<el-button type="danger" size="small">重置</el-button>
</template>
</el-popconfirm>
</td>
</tr>
</table>
</div>
</div>
<div class="node-item">
<div class="node-title">
<span>2.报告生成作业</span>
<el-text :type="NodeStateLevelDic[rateServe.report_work_node?.status]"
class="node-state-text">
{{ NodeStateNameDic[rateServe.report_work_node?.status] }}
</el-text>
</div>
<div class="node-content">
<table class="w-full fill-sheet-node-table" style="table-layout: fixed;">
<tr>
<th><span>初版报告</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline">生成</el-button>
</th>
<th><span>生成时间</span></th>
<th><span>终版报告</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline" @click="showFinalReportUpload">上传</el-button>
</th>
<th><span>上传时间</span></th>
<th></th>
<th colspan="2"><span>备注</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline"
@click="showRemarkEdit('report_work_node')">编辑
</el-button>
</th>
<th>操作
</th>
</tr>
<tr>
<td>
<el-button type="success" size="small">预览</el-button>
<el-button type="primary" size="small">下载</el-button>
</td>
<td>
{{ rateServe.report_work_node?.origin_create_time || '-' }}
</td>
<td>
<el-button type="success" size="small">预览</el-button>
<el-button type="primary" size="small">下载</el-button>
</td>
<td>
{{ rateServe.report_work_node?.final_create_time || '-' }}
</td>
<td></td>
<td colspan="2">
{{ rateServe.report_work_node?.remark || '-' }}
</td>
<td>
<el-popconfirm
width="220"
icon-color="#626AEF"
confirm-button-text="确定"
cancel-button-text="取消"
title="确认通过?"
>
<template #reference>
<el-button type="primary" size="small">通过</el-button>
</template>
</el-popconfirm>
<el-popconfirm
width="220"
:icon="WarningFilled as any"
:icon-color="'red'"
confirm-button-text="确定"
cancel-button-text="取消"
title="确认重置?"
>
<template #reference>
<el-button type="danger" size="small">重置</el-button>
</template>
</el-popconfirm>
</td>
</tr>
</table>
</div>
</div>
<div class="node-item">
<div class="node-title">
<span>3.证书生成作业</span>
<el-text :type="NodeStateLevelDic[rateServe.cert_work_node?.status]"
class="node-state-text">
{{ NodeStateNameDic[rateServe.cert_work_node?.status] }}
</el-text>
</div>
<div class="node-content">
<table class="w-full fill-sheet-node-table" style="table-layout: fixed;">
<tr>
<th><span>初版报告</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline">生成</el-button>
</th>
<th><span>生成时间</span></th>
<th></th>
<th></th>
<th></th>
<th colspan="2"><span>备注</span>
<el-button type="text" class="!text-[1rem] ml-1" style="vertical-align:baseline"
@click="showRemarkEdit('cert_work_node')">编辑
</el-button>
</th>
<th>操作
</th>
</tr>
<tr>
<td>
<el-button type="success" size="small">预览</el-button>
<el-button type="primary" size="small">下载</el-button>
</td>
<td>
{{ rateServe.cert_work_node?.create_time || '-' }}
</td>
<td></td>
<td></td>
<td></td>
<td colspan="2">
{{ rateServe.report_work_node?.remark || '-' }}
</td>
<td>
<el-popconfirm
width="220"
icon-color="#626AEF"
confirm-button-text="确定"
cancel-button-text="取消"
title="确认通过?"
>
<template #reference>
<el-button type="primary" size="small">通过</el-button>
</template>
</el-popconfirm>
<el-popconfirm
width="220"
:icon="WarningFilled as any"
:icon-color="'red'"
confirm-button-text="确定"
cancel-button-text="取消"
title="确认重置?"
>
<template #reference>
<el-button type="danger" size="small">重置</el-button>
</template>
</el-popconfirm>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="flex">
<div class="ml-auto mx-4 my-2">
<el-button size="small" type="warning" @click="cancelWork">取消</el-button>
<el-button size="small" type="danger" @click="deleteWork">删除</el-button>
<el-button size="small" type="primary" @click="finishWork">完成</el-button>
</div>
</div>
<el-dialog style="width: 32rem" title="取消" center v-model="cancelWorkVisible" append-to-body>
<div class="m-2">状态明细</div>
<el-input type="textarea" :rows="6" v-model="cancelRemark" placeholder="请输入不通过原因"></el-input>
<template #footer>
<div class="flex">
<div class="ml-auto">
<el-button type="info" size="small" @click="cancelWorkVisible=false">取消</el-button>
<el-button type="primary" size="small" @click="confirmCancelWork">确定</el-button>
</div>
</div>
</template>
</el-dialog>
<el-dialog style="width: 32rem" title="删除作业" center v-model="deleteWorkVisible" append-to-body>
<div class="m-2">状态明细</div>
<el-input type="textarea" :rows="6" v-model="deleteRemark" placeholder="请输入备注"></el-input>
<template #footer>
<div class="flex">
<div class="ml-auto">
<el-button type="info" size="small" @click="deleteWorkVisible=false">取消</el-button>
<el-button type="primary" size="small" @click="confirmDeleteWork">确定</el-button>
</div>
</div>
</template>
</el-dialog>
<el-dialog style="width: 32rem" title="完成作业" center v-model="finishWorkVisible" append-to-body>
<div class="m-2">状态明细</div>
<el-input type="textarea" :rows="6" v-model="finishRemark" placeholder="请输入完成备注"></el-input>
<template #footer>
<div class="flex">
<div class="ml-auto">
<el-button type="info" size="small" @click="finishWorkVisible=false">取消</el-button>
<el-button type="primary" size="small" @click="confirmFinishWork">确定</el-button>
</div>
</div>
</template>
</el-dialog>
<el-dialog title="编辑备注" style="width: 32rem" center v-model="nodeRemarkEditVisible">
<div class="m-2">备注信息</div>
<el-input type="textarea" :rows="6" v-model="editRemarkNodeTemp.remark" placeholder="请输入备注信息"></el-input>
<template #footer>
<div class="flex">
<div class="ml-auto">
<el-button type="info" size="small" @click="nodeRemarkEditVisible=false">取消</el-button>
<el-button type="primary" size="small" @click="confirmNodeRemarkEdit">确定</el-button>
</div>
</div>
</template>
</el-dialog>
<el-dialog style="width: 30rem" title="终版报告文件上传" v-model="finalReportUploadVisible">
<file-upload-md v-model="rateServe.rate_post_data_check_node.file_id"
ref="finalReportUploadRef"></file-upload-md>
<template #footer>
<div class="flex">
<div class="ml-auto">
<el-button type="info" size="small" @click="finalReportUploadVisible=false">取消</el-button>
<el-button type="primary" size="small" @click="confirmFinalReportUpload">确定</el-button>
</div>
</div>
</template>
</el-dialog>
</div>
</el-card>
</template>
<script setup lang="ts">
import {RateServe} from "@/views/smebiz/types";
import {
NodeStateLevelDic,
NodeStateNameDic,
RateServeStateLevelDic,
RateServeStateNameDic
} from "@/views/smebiz/config";
import {ref} from "vue";
import {ElMessage} from "element-plus";
import {WarningFilled} from '@element-plus/icons-vue'
import FileUploadMd from "@/components/EditTabel/fileUploadMd.vue";
const prop = defineProps<{ rateServe: RateServe }>()
const cancelWorkVisible = ref(false)
const deleteWorkVisible = ref(false)
const finishWorkVisible = ref(false)
const cancelRemark = ref('取消该作业')
const deleteRemark = ref('删除该作业')
const finishRemark = ref('已完成评级作业')
const editRemarkNodeTemp = ref({
nodeName: '',
remark: ''
})
const nodeRemarkEditVisible = ref(false)
const finalReportUploadVisible = ref(false)
const finalReportUploadRef = ref(null)
const showFinalReportUpload = () => {
finalReportUploadVisible.value = true
}
const confirmFinalReportUpload = () => {
finalReportUploadVisible.value = false
}
const showRemarkEdit = (nodeName) => {
editRemarkNodeTemp.value = {
nodeName: nodeName,
remark: prop.rateServe[nodeName]?.remark
}
nodeRemarkEditVisible.value = true
}
const confirmNodeRemarkEdit = () => {
nodeRemarkEditVisible.value = false
ElMessage.success("保存成功")
}
const cancelWork = () => {
cancelWorkVisible.value = true
}
const confirmCancelWork = () => {
cancelWorkVisible.value = false
ElMessage.success("已取消审核")
}
const deleteWork = () => {
deleteWorkVisible.value = true
}
const confirmDeleteWork = () => {
deleteWorkVisible.value = false
ElMessage.success("已删除")
}
const finishWork = () => {
finishWorkVisible.value = true
}
const confirmFinishWork = () => {
finishWorkVisible.value = false
ElMessage.success("已通过审核")
}
</script>
<style lang="scss">
.rate-workflow {
height: 100%;
overflow-y: auto;
//border: 1px dashed;
font-size: 1rem;
.el-card__body {
height: 100%;
}
}
</style>
<style scoped lang="scss">
.rate-serve-info {
padding: 1rem;
//border-bottom: 1px dashed;
}
.rate-serve-state {
@apply mx-8 text-2xl font-bold flex-c
}
.rate-serve-info__items {
div > :nth-child(1) {
font-weight: bold;
@apply mx-2
}
div > :nth-child(2) {
}
@apply grid grid-cols-2 gap-2 flex-1 mr-8
}
.fill-sheet-node-table {
th {
@apply py-2
}
td {
text-align: center;
@apply pt-2
}
}
.node-item {
@apply px-4 my-2 py-1
}
.node-title {
@apply flex my-2 w-52
}
.node-state-text {
margin-left: auto !important; /* 8px */
;
margin-right: 0.5rem !important /* 8px */
;
font-size: 1rem !important;
}
.node-content {
border: 1px dashed var(--el-border-color);
@apply pt-4 pb-6
}
</style>

View File

@ -1,13 +1,25 @@
import {RateServeState, NodeState} from "./types"
const RateServeStateNameDic: { [key in RateServeState]: any } = {
finish: "完成",
finish: "完成",
rating: "评级中",
cancel: "取消",
examining: "审核中"
}
const RateServeStateLevelDic: { [key in RateServeState]: any } = {
finish: "success",
rating: "primary",
cancel: "info",
examining: "primary"
}
const NodeStateNameDic: { [key in NodeState]: any } = {
finish: "完成",
finish: "完成",
incomplete: "未完成"
}
export {RateServeStateNameDic, NodeStateNameDic}
const NodeStateLevelDic: { [key in NodeState]: any } = {
finish: "success",
incomplete: "warning"
}
export {RateServeStateNameDic, NodeStateNameDic, RateServeStateLevelDic, NodeStateLevelDic}

View File

@ -20,7 +20,7 @@
</div>
</div>
<el-divider style="margin: 0.6rem"/>
<el-table class="flex-1 data-edit-table" :data="data" style="width: 100%">
<el-table empty-text="-" class="flex-1 data-edit-table" :data="data" style="width: 100%">
<el-table-column prop="serve_id" label="服务编号" align="center" width="200"/>
<el-table-column prop="company.name" label="受评主体" align="center" width="200"/>
<el-table-column prop="status" label="服务状态" align="center">
@ -37,12 +37,13 @@
<el-button
type="primary"
size="small"
@click="showExaminePage"
@click="showExaminePage(scope.row)"
>审核
</el-button>
<el-button
type="primary"
size="small"
@click="showRateWorkPage(scope.row)"
>作业
</el-button>
</div>
@ -61,9 +62,15 @@
@current-change="getData"
/>
</div>
<el-dialog title="中小商企评级服务审核" class="dialog-page" v-model="examinePageVisible" append-to-body>
<el-dialog title="中小商企评级服务审核" center class="dialog-page" v-model="examinePageVisible">
<examine-work class="h-full" :rate-serve="selectRow"></examine-work>
</el-dialog>
<el-dialog title="中小商企评级服务评级" center class="dialog-page" v-model="rateWorkPageVisible">
<rate-work class="w-full" :rate-serve="selectRow"></rate-work>
</el-dialog>
<el-dialog class="preview" v-model="previewShow">
<iframe :src="'https://testapi.fecribd.com'+fileUrl" style="width: 100%;height: 100%"></iframe>
</el-dialog>
</div>
</template>
<script setup lang="ts">
@ -71,9 +78,10 @@ import {api} from "@/api/api";
import {ElMessage, ElMessageBox} from "element-plus";
import {computed, onActivated, onMounted, ref} from "vue";
import {Check, Search, WarningFilled} from "@element-plus/icons-vue";
import {RateServe} from "./types";
import {NodeState, RateServe} from "./types";
import {RateServeStateNameDic} from "@/views/smebiz/config";
import ExamineWork from "@/views/smebiz/components/ExamineWork.vue";
import RateWork from "@/views/smebiz/components/RateWork.vue";
defineOptions({
name: "rateServeManage"
@ -85,10 +93,56 @@ const data = ref<RateServe[]>([
company_id: "QWEQASDASD",
rate_work_node: {
serve_id: "XP2308120617EMHJL",
rank: null,
status: 'incomplete'
rank: "AAA",
scope: 99,
status: 'finish',
rate_time:"2023-8-12 16:00"
},
company: {id: "QWEQASDASD", name: "远东资信评估有限公司"},
rate_post_data_check_node: {
serve_id: "XP2308120617EMHJL",
file_id: null,
file: null,
data: null,
parse_data: null,
status: 'incomplete',
remark: '',
create_time: null,
finish_time: null,
},
rate_data_preparation_node: {
serve_id: "XP2308120617EMHJL",
data: {},
status: "incomplete",
remark: "",
rate_time: null,
create_time: null,
finish_time: null
},
cert_work_node: {
serve_id: "XP2308120617EMHJL",
file: null,
file_id: null,
status: "incomplete",
remark: "",
create_time: null,
finish_time: null
},
report_work_node: {
serve_id: "XP2308120617EMHJL",
origin_create_time: null,
origin_file: null,
origin_file_id: null,
final_create_time: null,
final_file: null,
final_file_id: null,
status: "incomplete",
remark: "",
create_time: null,
finish_time: null
},
create_time: "2023-08-12",
finish_time: null
}
@ -100,6 +154,7 @@ const query = ref({
page_size: 20
});
const examinePageVisible = ref(false)
const rateWorkPageVisible = ref(false)
const selectRow = ref<RateServe | null>(data.value[0])
function exincludeNull(obj: {}) {
@ -131,6 +186,10 @@ const showExaminePage = (row: RateServe) => {
selectRow.value = row
examinePageVisible.value = true
}
const showRateWorkPage = (row: RateServe) => {
selectRow.value = row
rateWorkPageVisible.value = true
}
onMounted(() => {
console.log(data.value)
@ -147,7 +206,8 @@ onActivated(() => {
margin: 0;
width: 100%;
height: 100%;
> .el-dialog__body{
> .el-dialog__body {
height: 93%;
padding-top: 0;
}

View File

@ -64,7 +64,7 @@ interface RatePostDataCheckNode {
file_id?: string
file?: UploadFile
data?: any
parse_daya?: any
parse_data?: any
status: NodeState
remark?: string
create_time?: string

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import logo from "@/assets/login/logo.png";
import logo from "@/assets/login/logo2.png";
import { useUserStoreHook } from "@/store/modules/user";
import { setToken, getToken, DataInfo } from "@/utils/auth";
import { onMounted } from "vue";

View File

@ -1,27 +1,36 @@
<template>
<div class="flex flex-col" style="height: 100%;">
<el-table
v-bind="mainElTableProps"
class="flex-1 table-plus"
:data="tableData"
height="100%"
v-bind="mainElTableProps"
class="flex-1 table-plus"
:data="tableData"
height="100%"
>
<template #empty>
<el-empty description="无数据"/>
</template>
<el-table-column align="center" :label="column.name||column.key"
v-for="column in tableModel.columns.filter(item=>showColumnKeys.indexOf(item.key)!==-1)">
<template #header>
<query-column
@change="getTableData"
:ctx="query"
:column="column"
:model-value="getQueryValue(column,query)"
@update:model-value="(newValue)=>setQueryValue(column,query,newValue)"
/>
</template>
<template #default="{ row }">
<cell-column
class="overflow-auto"
:column="column"
:model-value="getValueFromPath(column.key,row)"
@update:model-value="(newVal)=>setValueFromPath(column.key,newVal,row)"
:ctx="row"
class="overflow-auto"
:column="column"
:model-value="getValueFromPath(column.key,row)"
@update:model-value="(newVal)=>setValueFromPath(column.key,newVal,row)"
:ctx="row"
/>
</template>
</el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="85">
<el-table-column align="center" fixed="right" label="操作" width="85">
<template #header>
<el-popover width="auto" trigger="click">
<template #reference>
@ -30,10 +39,10 @@
<div class="flex-c flex flex-col">
<div v-for="item in tableButtonConfig">
<el-button
class="block m-1.5"
type="primary"
size="small"
@click="item.func">
class="block m-1.5"
type="primary"
size="small"
@click="item.func">
{{ item.name }}
</el-button>
</div>
@ -43,9 +52,9 @@
<template #default="scope">
<div>
<el-button
type="primary"
size="small"
@click="() => itemEditDialogRef.show(scope.row)">
type="primary"
size="small"
@click="() => itemEditDialogRef.show(scope.row)">
编辑
</el-button>
</div>
@ -54,18 +63,18 @@
</el-table>
<div class="flex justify-center mt-1.5">
<el-pagination
v-model:current-page="query.page"
v-model:page-size="query.page_size"
@size-change="getTableData"
:page-sizes="[10, 20,30,40]"
:small="false"
layout="total,sizes,prev,pager,next"
:total="count"
@current-change="getTableData"
v-model:current-page="query.page"
v-model:page-size="query.page_size"
@size-change="getTableData"
:page-sizes="[10, 20,30,40]"
:small="false"
layout="total,sizes,prev,pager,next"
:total="count"
@current-change="getTableData"
/>
</div>
<item-edit-dialog ref="itemEditDialogRef" v-bind="props" @change="getTableData"/>
<item-add-dialog ref="itemAddDialogRef" v-bind="props" @change="getTableData"/>
<item-edit-dialog ref="itemEditDialogRef" v-bind="props" @change="getTableData"/>
<item-add-dialog ref="itemAddDialogRef" v-bind="props" @change="getTableData"/>
<table-config-dialog ref="tableConfigDialogRef" :tableModel="tableModel"
v-model:showColumnKeys="showColumnKeys"/>
</div>
@ -73,14 +82,16 @@
<script setup lang="ts">
import type {ElTable} from "element-plus";
import {ElMessage} from "element-plus";
import {computed, onMounted, ref, watch} from "vue";
import {computed, ref, watch} from "vue";
import type {TablePlusProps} from "./types";
import CellColumn from "./components/CellColumn/index.vue";
import QueryColumn from "./components/QueryColumn/index.vue";
import TableConfigDialog from "./components/TableConfigDialog.vue";
import {useColumns} from "./setups"
import ItemEditDialog from "./components/ItemEditDialog.vue";
import ItemAddDialog from "./components/ItemAddDialog.vue";
import {getValueFromPath, setValueFromPath} from "./utils";
import {getQueryValue, getValueFromPath, setQueryValue, setValueFromPath} from "./utils";
import {Query} from "./api";
const props = withDefaults(defineProps<TablePlusProps>(), {
tableModel: null,
@ -92,7 +103,7 @@ const props = withDefaults(defineProps<TablePlusProps>(), {
const showColumnKeys = ref([])
const tableData = ref([]);
const count = ref(0);
const query = ref({page: 1, page_size: 20});
const query = ref<Query>({params: [], page: 1, page_size: 20});
const {idKey, crudApi} = useColumns(props)
const itemEditDialogRef = ref<InstanceType<typeof ItemEditDialog> | null>(null)
const itemAddDialogRef = ref<InstanceType<typeof ItemAddDialog> | null>(null)
@ -104,18 +115,18 @@ const tableButtonConfig = computed(() => [
{name: "表格配置", func: tableConfigDialogRef.value?.show},
])
watch(
() => props.tableModel,
newVal => {
getTableData();
},
{deep: true, immediate: true}
() => props.tableModel,
newVal => {
getTableData();
},
{deep: true, immediate: true}
);
async function getTableData() {
//todo:
//
try {
const res = await crudApi.value.queryCommon(query.value);
const res = await crudApi.value.queryCommon({...query.value,params:query.value.params.filter(item=>[null,undefined,""].indexOf(item.value)===-1)});
count.value = res.data.count;
tableData.value = res.data.items;
} catch (e) {

View File

@ -19,11 +19,10 @@ interface QueryParam {
}
export interface OrderParam {
order_by: string;
type: "asc" | "desc";
[key: string]: "asc" | "desc" | null
}
interface QueryParams {
interface Query {
params?: QueryParam[];
order?: OrderParam;
relation_use_id?: boolean;
@ -60,13 +59,13 @@ class CrudApi {
});
}
async queryCommon(queryParams: QueryParams) {
async queryCommon(query: Query) {
return await api.post<any, any>(
this.baseUrl + "/query",
queryParams
query
);
}
}
export {CrudApi};
export type {QueryParams, QueryParam, QueryExpress};
export type {Query, QueryParam, QueryExpress};

View File

@ -88,7 +88,7 @@ async function addItem(formEl: FormInstance) {
props.handel?.afterDataChange?.()
})
.catch(e => {
ElMessage.warning("错误");
ElMessage.warning(e.response?.data?.detail || e.response?.statusText);
throw e;
});
} else {

View File

@ -126,7 +126,7 @@ function show(item: any) {
itemEditVisible.value = true;
}).catch(
e => {
ElMessage.warning("错误");
ElMessage.warning(e.response?.data?.detail || e.response?.statusText);
throw e;
}
)

View File

@ -1,62 +1,71 @@
<template>
<div class="flex flex-col" >
<el-table
v-bind="mainElTableProps"
class="table-plus flex-1"
:data="tableData"
:reserve-selection="true"
@select="handleSelect"
@select-all="handleSelect"
:row-key="idKey"
ref="table"
>
<template #empty>
<el-empty description="无数据"/>
<div class="flex flex-col">
<el-table
v-bind="mainElTableProps"
class="table-plus flex-1"
:data="tableData"
:reserve-selection="true"
@select="handleSelect"
@select-all="handleSelect"
:row-key="idKey"
ref="table"
>
<template #empty>
<el-empty description="无数据"/>
</template>
<el-table-column align="center" type="selection"/>
<el-table-column align="center" :label="column.name||column.key"
v-for="column in tableModel.columns.filter(item=>showColumnKeys.indexOf(item.key)!==-1)">
<template #header>
<query-column
@change="getTableData"
:ctx="query"
:column="column"
:model-value="getQueryValue(column,query)"
@update:model-value="(newValue)=>setQueryValue(column,query,newValue)"
/>
</template>
<el-table-column align="center" type="selection"/>
<el-table-column align="center" :label="column.name||column.key"
v-for="column in tableModel.columns.filter(item=>showColumnKeys.indexOf(item.key)!==-1)">
<template #default="{ row }">
<cell-column
class="overflow-auto"
:column="column"
:model-value="getValueFromPath(column.key,row)"
@update:model-value="(newVal)=>setValueFromPath(column.key,newVal,row)"
<template #default="{ row }">
<cell-column
class="overflow-auto"
:column="column"
:model-value="getValueFromPath(column.key,row)"
@update:model-value="(newVal)=>setValueFromPath(column.key,newVal,row)"
:ctx="row"/>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="85">
<template #header>
<el-popover width="auto" trigger="click">
<template #reference>
<el-button size="small">操作</el-button>
</template>
<div class="flex-c flex flex-col">
<div v-for="item in tableButtonConfig">
<el-button
class="block m-1.5"
type="primary"
size="small"
@click="item.func">
{{ item.name }}
</el-button>
</div>
:ctx="row"/>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="85">
<template #header>
<el-popover width="auto" trigger="click">
<template #reference>
<el-button size="small">操作</el-button>
</template>
<div class="flex-c flex flex-col">
<div v-for="item in tableButtonConfig">
<el-button
class="block m-1.5"
type="primary"
size="small"
@click="item.func">
{{ item.name }}
</el-button>
</div>
</el-popover>
</template>
<template #default="scope">
<div>
<el-button
type="primary"
size="small"
@click="() => itemEditDialogRef.show(scope.row)">
编辑
</el-button>
</div>
</template>
</el-table-column>
</el-table>
</el-popover>
</template>
<template #default="scope">
<div>
<el-button
type="primary"
size="small"
@click="() => itemEditDialogRef.show(scope.row)">
编辑
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="flex justify-center mt-1.5">
<el-pagination
v-model:current-page="query.page"
@ -69,7 +78,7 @@
@current-change="getTableData"
/>
</div>
<item-edit-dialog ref="itemEditDialogRef" v-bind="props" @change="getTableData"/>
<item-edit-dialog ref="itemEditDialogRef" v-bind="props" @change="getTableData"/>
<item-add-dialog ref="itemAddDialogRef" v-bind="props" @change="getTableData"/>
</div>
@ -77,13 +86,15 @@
<script setup lang="ts">
import type {ElTable} from "element-plus";
import {ElMessage} from "element-plus";
import {computed, onMounted, ref, watch, nextTick} from "vue";
import {computed, nextTick, ref, watch} from "vue";
import type {MultipleSelectTableProps} from "../types";
import CellColumn from "./CellColumn/index.vue";
import {useColumns} from "../setups"
import ItemEditDialog from "./ItemEditDialog.vue";
import ItemAddDialog from "./ItemAddDialog.vue";
import {getValueFromPath, setValueFromPath} from "../utils";
import {getQueryValue, getValueFromPath, setQueryValue, setValueFromPath} from "../utils";
import QueryColumn from "./QueryColumn/index.vue";
import {Query} from "../api";
const props = withDefaults(defineProps<MultipleSelectTableProps>(), {
tableModel: null,
@ -96,7 +107,7 @@ const emit = defineEmits(['update:selection'])
const showColumnKeys = ref([])
const tableData = ref([]);
const count = ref(0);
const query = ref({page: 1, page_size: 20});
const query = ref<Query>({params: [], page: 1, page_size: 20});
const {idKey, crudApi} = useColumns(props)
const itemEditDialogRef = ref<InstanceType<typeof ItemEditDialog> | null>(null)
const itemAddDialogRef = ref<InstanceType<typeof ItemAddDialog> | null>(null)
@ -115,14 +126,14 @@ watch(() => props.tableModel, () => {
showColumnKeys.value = showColumnKeysTemp
}, {immediate: true})
watch(() => props.selection, newVal => {
console.log(newVal,"sssss")
console.log(newVal, "sssss")
nextTick(selectRows)
}, {immediate: true})
function selectRows() {
if (tableData.value && props.selection) {
tableData.value.forEach(row => {
if (props.selection.map(item=>item[idKey.value]).indexOf(row[idKey.value]) !== -1) {
if (props.selection.map(item => item[idKey.value]).indexOf(row[idKey.value]) !== -1) {
table.value.toggleRowSelection(row, true)
} else {
table.value.toggleRowSelection(row, false)
@ -143,7 +154,7 @@ const handleSelect = (val) => {
async function getTableData() {
//todo:
try {
const res = await crudApi.value.queryCommon(query.value);
const res = await crudApi.value.queryCommon({...query.value,params:query.value.params.filter(item=>[null,undefined,""].indexOf(item.value)===-1)});
count.value = res.data.count;
tableData.value = res.data.items;
await nextTick(selectRows)

View File

@ -5,7 +5,6 @@
class="one-select-table-plus flex-1"
highlight-current-row
:data="tableData"
@current-change="handleCurrentChange"
:row-key="idKey"
ref="table"
>
@ -14,6 +13,15 @@
</template>
<el-table-column align="center" :label="column.name||column.key"
v-for="column in tableModel.columns.filter(item=>showColumnKeys.indexOf(item.key)!==-1)">
<template #header>
<query-column
@change="getTableData"
:ctx="query"
:column="column"
:model-value="getQueryValue(column,query)"
@update:model-value="(newValue)=>setQueryValue(column,query,newValue)"
/>
</template>
<template #default="{ row }">
<cell-column
class="overflow-auto"
@ -95,7 +103,9 @@ import CellColumn from "./CellColumn/index.vue";
import {useColumns} from "../setups"
import ItemEditDialog from "./ItemEditDialog.vue";
import ItemAddDialog from "./ItemAddDialog.vue";
import {copy, getValueFromPath, setValueFromPath} from "../utils";
import {copy, getQueryValue, getValueFromPath, setQueryValue, setValueFromPath} from "../utils";
import QueryColumn from "./QueryColumn/index.vue";
import {Query} from "../api";
const props = withDefaults(defineProps<OneSelectTableProps>(), {
tableModel: null,
@ -106,7 +116,7 @@ const emit = defineEmits(['update:value'])
const showColumnKeys = ref([])
const tableData = ref([]);
const count = ref(0);
const query = ref({page: 1, page_size: 20});
const query = ref<Query>({params:[],page: 1, page_size: 20});
const {idKey, crudApi} = useColumns(props)
const itemEditDialogRef = ref<InstanceType<typeof ItemEditDialog> | null>(null)
const itemAddDialogRef = ref<InstanceType<typeof ItemAddDialog> | null>(null)
@ -138,7 +148,8 @@ const handleCurrentChange = (val) => {
async function getTableData() {
//todo:
try {
const res = await crudApi.value.queryCommon(query.value);
const res = await crudApi.value.queryCommon({...query.value,params:query.value.params.filter(item=>[null,undefined,""].indexOf(item.value)===-1)});
count.value = res.data.count;
tableData.value = res.data.items;
await nextTick(() => setCurrent(props.value))

View File

@ -0,0 +1,32 @@
<template>
<el-date-picker
style="width: 6rem"
v-model="value"
type="date"
:placeholder="column.name"
value-format="YYYY-MM-DD HH:mm:ss"
size="small"
/>
</template>
<script setup lang="ts">
import {computed, defineEmits, defineProps} from "vue";
import type {Column} from "../../types";
const props = defineProps<{ column: Column; modelValue: any }>();
const emit = defineEmits(["update:modelValue", "change"]);
const value = computed({
get() {
return props.modelValue;
},
set(newVal) {
emit("update:modelValue", newVal);
emit("change", newVal);
}
});
const change = (index, e) => {
props.modelValue[index] = e
emit("update:modelValue", props.modelValue);
emit("change", props.modelValue);
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<div v-if="modelValue" >
<el-date-picker
style="width: 6rem"
v-model="modelValue[0]"
type="date"
:placeholder="'column.name-'+'开始'"
value-format="YYYY-MM-DD HH:mm:ss"
size="small"
@change="(e)=>change(0,e)"
/>
<el-date-picker
style="width: 6rem"
v-model="modelValue[1]"
type="date"
:placeholder="'column.name-'+'结束'"
value-format="YYYY-MM-DD HH:mm:ss"
size="small"
@change="(e)=>change(1,e)"
/>
</div>
</template>
<script setup lang="ts">
import {computed, defineEmits, defineProps, onMounted, ref} from "vue";
import type {Column} from "../../types";
const props = defineProps<{ column: Column; modelValue: any }>();
const emit = defineEmits(["update:modelValue", "change"]);
const value = computed({
get() {
return props.modelValue;
},
set(newVal) {
emit("update:modelValue", newVal);
emit("change", newVal);
}
});
const change = (index, e) => {
props.modelValue[index] = e
emit("update:modelValue", props.modelValue);
emit("change", props.modelValue);
}
</script>

View File

@ -0,0 +1,32 @@
<template>
<el-date-picker
style="width: 6rem"
v-model="value"
type="date"
:placeholder="column.name"
value-format="YYYY-MM-DD HH:mm:ss"
size="small"
/>
</template>
<script setup lang="ts">
import {computed, defineEmits, defineProps, onMounted, ref} from "vue";
import type {Column} from "../../types";
const props = defineProps<{ column: Column; modelValue: any }>();
const emit = defineEmits(["update:modelValue", "change"]);
const value = computed({
get() {
return props.modelValue;
},
set(newVal) {
emit("update:modelValue", newVal);
emit("change", newVal);
}
});
const change = (index, e) => {
props.modelValue[index] = e
emit("update:modelValue", props.modelValue);
emit("change", props.modelValue);
}
</script>

View File

@ -0,0 +1,35 @@
<template>
<div v-if="value">
<el-date-picker
style="width: 6rem"
v-model="value[0]"
type="datetime"
:placeholder="'column.name-'+'开始'"
size="small"
/>
<el-date-picker
style="width: 6rem"
v-model="value[1]"
type="datetime"
:placeholder="'column.name-'+'结束'"
size="small"
/>
</div>
</template>
<script setup lang="ts">
import { computed, defineProps, defineEmits } from "vue";
import type { Column } from "../../types";
const props = defineProps<{ column: Column; modelValue:any }>();
const emit = defineEmits(["update:modelValue", "change"]);
const value = computed({
get() {
return props.modelValue;
},
set(newVal) {
emit("update:modelValue", newVal);
emit("change", newVal);
}
});
</script>

View File

@ -0,0 +1,47 @@
<template>
<el-select
style="max-width: 12rem"
clearable
v-model="value"
size="small"
:placeholder="column.name"
filterable
>
<el-option
v-for="item in options"
:label="item.name"
:key="item.value"
:value="item.value"
/>
</el-select>
</template>
<script setup lang="ts">
import { computed, defineProps, defineEmits } from "vue";
import type { Column } from "../../types";
const props = defineProps<{ column: Column; modelValue:any }>();
const emit = defineEmits(["update:modelValue", "change"]);
const value = computed({
get() {
return props.modelValue;
},
set(newVal) {
emit("update:modelValue", newVal);
emit("change", newVal);
}
});
const options = computed(() => {
const options = props.column.query?.options||props.column.config?.options;
if (options instanceof Array && options.length) {
if (typeof options[0] === "object") {
return options;
} else {
return options.map(item => {
return { name: item, value: item };
});
}
}
return [];
});
</script>

View File

@ -0,0 +1,47 @@
<template>
<el-select
clearable
v-model="value"
size="small"
:placeholder="column.name"
style="max-width: 12rem"
filterable
>
<el-option
v-for="item in options"
:label="item.name"
:key="item.value"
:value="item.value"
/>
</el-select>
</template>
<script setup lang="ts">
import { computed, defineProps, defineEmits } from "vue";
import type { Column } from "../../types";
const props = defineProps<{ column: Column; modelValue:any }>();
const emit = defineEmits(["update:modelValue", "change"]);
const value = computed({
get() {
return props.modelValue;
},
set(newVal) {
emit("update:modelValue", newVal);
emit("change", newVal);
}
});
const options = computed(() => {
const options = props.column.config?.options;
if (options instanceof Array && options.length) {
if (typeof options[0] === "object") {
return options;
} else {
return options.map(item => {
return { name: item, value: item };
});
}
}
return [];
});
</script>

View File

@ -0,0 +1,47 @@
<template>
<component
v-if="componentUser?.component"
:is="componentUser?.component"
v-bind="{ ...componentUser?.props, column,ctx }"
v-model="value"
></component>
<component
v-else-if="components[column.query.type]"
:is="components[column.query.type]"
:column="column"
v-model="value"
></component>
<div v-else>{{ column.name }}</div>
</template>
<script setup lang="ts">
import dateQuery from "./dateQuery.vue";
import datetimeQuery from "./datetimeQuery.vue";
import enumQuery from "./enumQuery.vue";
import findInSetQuery from "./findInSetQuery.vue";
import likeQuery from "./likeQuery.vue";
import {computed, defineEmits, defineProps} from "vue";
import type {Column} from "../../types";
const props = defineProps<{ column: Column; modelValue: any; ctx: any }>();
const emit = defineEmits(["update:modelValue", "change"]);
const value = computed({
get() {
return props.modelValue;
},
set(newVal) {
emit("update:modelValue", newVal);
emit("change", newVal);
}
});
const componentUser = computed(
() => props.column?.component?.queryColumn
);
const components = {
date: dateQuery,
datetime: datetimeQuery,
enum: enumQuery,
find_in_set: findInSetQuery,
like: likeQuery
};
</script>

View File

@ -0,0 +1,26 @@
<template>
<el-input
clearable
size="small"
v-model="value"
:placeholder="column.name"
style="max-width: 12rem"
></el-input>
</template>
<script setup lang="ts">
import { computed, defineProps, defineEmits } from "vue";
import type { Column } from "../../types";
const props = defineProps<{ column: Column; modelValue:any }>();
const emit = defineEmits(["update:modelValue", "change"]);
const value = computed({
get() {
return props.modelValue;
},
set(newVal) {
emit("update:modelValue", newVal);
emit("change", newVal);
}
});
</script>

View File

@ -0,0 +1,24 @@
import {QueryExpress} from "@/api/crudApi";
import type {ColumnTypeName, QueryTypeEnum} from "./types";
//查询值的数据初始值
//查询配置的对应后端queryCommon类型
//新建数据时的字段默认值
const queryTypeDefaultValueDic: { [key in QueryTypeEnum]?: any } = {
date: null,
datetime: null,
// daterange: [null, null],
// datetimerange: [null, null]
}
const queryTypeExpressDic: { [key in QueryTypeEnum]: QueryExpress } = {
date: "=",
datetime: "=",
find_in_set: "find_in_set",
enum: "=",
like: "like",
}
export {
queryTypeDefaultValueDic,
queryTypeExpressDic,
};

View File

@ -1,260 +1,305 @@
///////////////////////
import {ElTable} from "element-plus";
type ColumnTypeName =
"string"
| "text"
| "datetime"
| "date"
| "integer"
| "double"
| "float"
| "boolean"
| "enum"
| "set"
| "list"
| "json"
| "relation"
| "o2mo"
| "o2mm"
| "m2m"
| "o2o"
| "foreign"
export type QueryTypeEnum = "like" | "date" | "datetime" | "enum" | "find_in_set";
interface QueryConfigBase {
type: QueryTypeEnum;
options?: any[] | { name: string; value: any }[];
}
interface QueryLike extends QueryConfigBase {
type: "like";
}
interface QueryDate extends QueryConfigBase {
type: "date";
}
interface QueryDatetime extends QueryConfigBase {
type: "datetime";
}
interface QueryEnum extends QueryConfigBase {
type: "enum";
options?: any[] | { name: string; value: any }[];
}
interface QueryFindInSet extends QueryConfigBase {
type: "find_in_set";
options?: any[] | { name: string; value: any }[];
}
export type QueryType =
| QueryLike
| QueryEnum
| QueryFindInSet
| QueryDate
| QueryDatetime
export type ColumnTypeName =
"string"
| "text"
| "datetime"
| "date"
| "integer"
| "double"
| "float"
| "boolean"
| "enum"
| "set"
| "list"
| "json"
| "relation"
| "o2mo"
| "o2mm"
| "m2m"
| "o2o"
| "foreign"
interface ColumnBase {
key: string
name: string
default?: any
primary?: boolean
require?: {
add?: boolean
update?: boolean
}
query?: {
type: ""
}
type: ColumnTypeName
config?: any
component?: {
//使用自定义组件
inputColumn?: ColumnComponent;//编辑字段组件
cellColumn?: ColumnComponent;//表格字段组件
queryColumn?: ColumnComponent;//查询字段组件
};
key: string
name: string
default?: any
primary?: boolean
require?: {
add?: boolean
update?: boolean
}
query?: QueryType
type: ColumnTypeName
config?: any
component?: {
//使用自定义组件
inputColumn?: ColumnComponent;//编辑字段组件
cellColumn?: ColumnComponent;//表格字段组件
queryColumn?: ColumnComponent;//查询字段组件
};
}
interface StringColumn extends ColumnBase {
type: "string"
config?: {
len?: number | { max?: number, min?: number }
re?: string
}
type: "string"
config?: {
len?: number | { max?: number, min?: number }
re?: string
}
}
interface TextColumn extends ColumnBase {
type: "text"
config?: {
len?: { max?: number, min?: number }
}
type: "text"
config?: {
len?: { max?: number, min?: number }
}
}
interface DatetimeColumn extends ColumnBase {
type: "datetime"
type: "datetime"
}
interface DateColumn extends ColumnBase {
type: "date"
type: "date"
}
interface IntegerColumn extends ColumnBase {
type: "integer"
config?: {
max?: number
min?: number
}
type: "integer"
config?: {
max?: number
min?: number
}
}
interface DoubleColumn extends ColumnBase {
type: "double"
config?: {
max?: number
min?: number
}
type: "double"
config?: {
max?: number
min?: number
}
}
interface FloatColumn extends ColumnBase {
type: "float"
config?: {
max?: number
min?: number
}
type: "float"
config?: {
max?: number
min?: number
}
}
interface BooleanColumn extends ColumnBase {
type: "boolean"
type: "boolean"
}
interface EnumColumn extends ColumnBase {
type: "enum"
config: {
options: any[] | { name: string, value: any }[]
}
type: "enum"
config: {
options: any[] | { name: string, value: any }[]
}
}
interface SetColumn extends ColumnBase {
type: "set",
config: {
options: any[] | { name: string, value: any }[]
}
type: "set",
config: {
options: any[] | { name: string, value: any }[]
}
}
interface ListColumn extends ColumnBase {
type: "list"
config: {
options: any[] | { name: string, value: any }[]
}
type: "list"
config: {
options: any[] | { name: string, value: any }[]
}
}
interface JsonColumn extends ColumnBase {
type: "json"
config: {
schema: TableModel
}
type: "json"
config: {
schema: JsonTableModel
}
}
// foreign不允许修改或者只能一次修改这一个字段
interface ForeignColumn extends ColumnBase {
type: "foreign"
config: {
targetModel: TableModel
key: string
nameKey: string | string[]
}
type: "foreign"
config: {
targetModel: TableModel
key: string
nameKey: string | string[]
}
}
interface RelationColumn extends ColumnBase {
type: "relation"
config: {
relationType: "o2m_o" | "o2m_m" | "m2m" | "o2o"
targetModel: TableModel
}
type: "relation"
config: {
relationType: "o2m_o" | "o2m_m" | "m2m" | "o2o"
targetModel: TableModel
}
}
//父子一对多关系里的父亲例如父子一个父亲对应多个儿子它的值应该是个id列表或者儿子模型列表
interface O2MOColumn extends ColumnBase {
type: "o2mo"
config: {
targetModel: TableModel
nameKey: string | string[]//字段值显示时使用的key
}
type: "o2mo"
config: {
targetModel: TableModel
nameKey: string | string[]//字段值显示时使用的key
}
}
//父子一对多关系里的儿子例如父子一个父亲对应多个儿子它的值应该是个id列表或者父亲模型
interface O2MMColumn extends ColumnBase {
type: "o2mm"
config: {
targetModel: TableModel
}
type: "o2mm"
config: {
targetModel: TableModel
}
}
interface O2OColumn extends ColumnBase {
type: "o2o"
config: {
targetModel: TableModel
nameKey: string | string[]
//有这个字段的,可以创建与更新和选择
//没有这个字段,只能创建与更新
fromModelForeignKey?: string | null//从model的哪个key引用到targetModel的例如一对一父子关系的儿子里面的parent_id
}
type: "o2o"
config: {
targetModel: TableModel
nameKey: string | string[]
//有这个字段的,可以创建与更新和选择
//没有这个字段,只能创建与更新
fromModelForeignKey?: string | null//从model的哪个key引用到targetModel的例如一对一父子关系的儿子里面的parent_id
}
}
//多对多关系
interface M2MColumn extends ColumnBase {
type: "m2m"
config: {
targetModel: TableModel
nameKey: string | string[]//字段值显示时使用的key
}
type: "m2m"
config: {
targetModel: TableModel
nameKey: string | string[]//字段值显示时使用的key
}
}
type Column =
StringColumn
| TextColumn
| DateColumn
| DoubleColumn
| DatetimeColumn
| RelationColumn
| ListColumn
| SetColumn
| FloatColumn
| IntegerColumn
| JsonColumn
| BooleanColumn
| EnumColumn
| O2MOColumn
| M2MColumn
| O2OColumn
| ForeignColumn
StringColumn
| TextColumn
| DateColumn
| DoubleColumn
| DatetimeColumn
| RelationColumn
| ListColumn
| SetColumn
| FloatColumn
| IntegerColumn
| JsonColumn
| BooleanColumn
| EnumColumn
| O2MOColumn
| M2MColumn
| O2OColumn
| ForeignColumn
interface ColumnComponent {
component: any;
props?: any;
component: any;
props?: any;
}
interface JsonTableModel {
columns: Column[]
props?: {
//在表格中隐藏的字段
hiddenColumns?: string[]
}
}
interface TableModel {
tableName: string
url: string
name: string
columns: Column[]
props?: {
//在表格中隐藏的字段
hiddenColumns?: string[]
}
tableName: string
url: string
name: string
columns: Column[]
props?: {
//在表格中隐藏的字段
hiddenColumns?: string[]
}
}
export type {
TableModel,
Column,
TextColumn,
DateColumn,
DoubleColumn,
DatetimeColumn,
RelationColumn,
ListColumn,
SetColumn,
FloatColumn,
IntegerColumn,
JsonColumn,
BooleanColumn,
EnumColumn,
StringColumn,
O2MOColumn,
M2MColumn,
O2OColumn,
ForeignColumn
TableModel,
Column,
TextColumn,
DateColumn,
DoubleColumn,
DatetimeColumn,
RelationColumn,
ListColumn,
SetColumn,
FloatColumn,
IntegerColumn,
JsonColumn,
BooleanColumn,
EnumColumn,
StringColumn,
O2MOColumn,
M2MColumn,
O2OColumn,
ForeignColumn
}
type MainElTableProps = InstanceType<typeof ElTable>["$props"];
export interface TablePlusProps {
tableModel: TableModel;
mainElTableProps?: MainElTableProps;
formLabelWidth?: number;
handel?: {
afterDataChange?: () => any,
afterDelete?: () => any,
afterUpdate?: () => any,
afterAdd?: () => any,
}
tableModel: TableModel;
mainElTableProps?: MainElTableProps;
formLabelWidth?: number;
handel?: {
afterDataChange?: () => any,
afterDelete?: () => any,
afterUpdate?: () => any,
afterAdd?: () => any,
}
}
export interface MultipleSelectTableProps extends TablePlusProps {
selection?: null | string[]
selection?: null | string[]
}
export interface OneSelectTableProps extends TablePlusProps {
value: any
value: any
}

View File

@ -1,4 +1,6 @@
import {Column} from "./types";
import {Query} from "./api";
import {queryTypeExpressDic} from "./config";
export function copy(obj: any) {
return obj ? JSON.parse(JSON.stringify(obj)) : obj
@ -69,4 +71,46 @@ export function getColumnDefaultValue(column: Column) {
}
export function getColumnQueryDefaultValue(column: Column) {
if (column.query) {
if (column.query.type == 'like') {
} else if (column.query.type == 'enum') {
} else if (column.query.type == 'date') {
} else if (column.query.type == 'datetime') {
} else if (column.query.type == 'find_in_set') {
}
}
return null
}
export function getQueryValue(column: Column, query: Query) {
let param = query.params.find(item => item.name == column.key)
if (!param) {
param = {
name: column.key,
type: queryTypeExpressDic[column.query.type],
value: null
}
query.params.push(param)
}
return param.value
}
export function setQueryValue(column: Column, query: Query, value) {
let param = query.params.find(item => item.name == column.key)
if (!param) {
param = {
name: column.key,
type: queryTypeExpressDic[column.query.type],
value: null
}
query.params.push(param)
}
param.value = value
}

View File

@ -58,7 +58,7 @@ export default ({command, mode}: ConfigEnv): UserConfigExport => {
exclude
},
build: {
outDir:"wd-smebiz-manage-web",
outDir:"wd-smebiz-manage-web-v2",
sourcemap: false,
// 消除打包大小超过500kb警告
chunkSizeWarningLimit: 4000,