fix: 数据库查询结果日期格式化

This commit is contained in:
刘宗洋
2023-12-15 11:29:57 +08:00
parent a5a813f95f
commit 61aed08dde
9 changed files with 233 additions and 59 deletions

View File

@@ -7,6 +7,7 @@ export function dateFormat2(fmt: string, date: Date) {
'H+': date.getHours().toString(), // 时
'm+': date.getMinutes().toString(), // 分
's+': date.getSeconds().toString(), // 秒
'S+': date.getMilliseconds() ? date.getMilliseconds().toString() : '', // 毫秒
// 有其他格式化字符需求可以继续添加,必须转化成字符串
};
for (const k in opt) {

View File

@@ -428,7 +428,7 @@ const saveSql = async () => {
const input = await ElMessageBox.prompt('请输入SQL脚本名', 'SQL名', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPattern: /\w+/,
inputPattern: /\.+/,
inputErrorMessage: '请输入SQL脚本名',
});
sqlName = input.value;

View File

@@ -34,7 +34,10 @@
<!-- 字段名列 -->
<div v-else @contextmenu="headerContextmenuClick($event, column)" style="position: relative">
<div class="column-type">
<span class="font8">{{ dbDialect.getShortColumnType(column.columnType) }}</span>
<span v-if="ColumnTypeSubscript[dbDialect.getDataType(column.columnType)] === 'icon-clock'">
<SvgIcon :size="8" name="Clock" style="cursor: unset" />
</span>
<span class="font8" v-else>{{ ColumnTypeSubscript[dbDialect.getDataType(column.columnType)] }}</span>
</div>
<div v-if="showColumnTip" @mouseover="column.showSetting = true" @mouseleave="column.showSetting = false">
@@ -77,13 +80,49 @@
<div v-else @dblclick="onEnterEditMode(rowData, column, rowIndex, columnIndex)">
<div v-if="canEdit(rowIndex, columnIndex)">
<el-input
v-if="nowUpdateCell.dataType == DataType.Number || nowUpdateCell.dataType == DataType.String"
:ref="(el: any) => el?.focus()"
@blur="onExitEditMode(rowData, column, rowIndex)"
class="w100"
input-style="text-align: center; height: 26px;"
size="small"
v-model="rowData[column.dataKey!]"
></el-input>
/>
<el-date-picker
v-if="nowUpdateCell.dataType == DataType.Date"
:ref="(el: any) => el?.focus()"
@blur="onExitEditMode(rowData, column, rowIndex)"
class="edit-time-picker"
size="small"
v-model="rowData[column.dataKey!]"
:clearable="false"
type="Date"
value-format="YYYY-MM-DD"
placeholder="选择日期"
/>
<el-date-picker
v-if="nowUpdateCell.dataType == DataType.DateTime"
:ref="(el: any) => el?.focus()"
@blur="onExitEditMode(rowData, column, rowIndex)"
class="edit-time-picker"
size="small"
v-model="rowData[column.dataKey!]"
:clearable="false"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择日期时间"
/>
<el-time-picker
v-if="nowUpdateCell.dataType == DataType.Time"
:ref="(el: any) => el?.focus()"
@blur="onExitEditMode(rowData, column, rowIndex)"
class="edit-time-picker"
size="small"
v-model="rowData[column.dataKey!]"
:clearable="false"
value-format="HH:mm:ss"
placeholder="选择时间"
/>
</div>
<div v-else :class="isUpdated(rowIndex, column.dataKey) ? 'update_field_active' : ''">
@@ -143,7 +182,7 @@ import SvgIcon from '@/components/svgIcon/index.vue';
import { exportCsv, exportFile } from '@/common/utils/export';
import { dateStrFormat } from '@/common/utils/date';
import { useIntervalFn } from '@vueuse/core';
import { getDbDialect, DbDialect } from '../../dialect/index';
import { getDbDialect, DbDialect, ColumnTypeSubscript, DataType, DbType } from '../../dialect/index';
const emits = defineEmits(['dataDelete', 'sortChange', 'deleteData', 'selectionChange', 'changeUpdatedField']);
@@ -152,10 +191,6 @@ const props = defineProps({
type: Number,
required: true,
},
dbType: {
type: String,
default: '',
},
db: {
type: String,
required: true,
@@ -256,6 +291,7 @@ const cmDataExportSql = new ContextmenuItem('exportSql', '导出SQL')
class NowUpdateCell {
rowIndex: number;
colIndex: number;
dataType: DataType;
oldValue: any;
}
@@ -399,7 +435,7 @@ onMounted(async () => {
state.emptyText = props.emptyText;
state.dbId = props.dbId;
state.dbType = props.dbType;
state.dbType = getNowDbInst().type;
dbDialect = getDbDialect(state.dbType);
state.db = props.db;
@@ -415,10 +451,24 @@ onBeforeUnmount(() => {
endLoading();
});
const formatDataValues = (datas: any) => {
// mysql数据暂不做处理
if (DbType.mysql === getNowDbInst().type) {
return;
}
for (let data of datas) {
for (let column of props.columns!) {
data[column.columnName] = getFormatTimeValue(dbDialect.getDataType(column.columnType), data[column.columnName]);
}
}
};
const setTableData = (datas: any) => {
tableRef.value.scrollTo({ scrollLeft: 0, scrollTop: 0 });
selectionRowsMap.clear();
cellUpdateMap.clear();
formatDataValues(datas);
state.datas = datas;
setTableColumns(props.columns);
};
@@ -629,6 +679,7 @@ const onEnterEditMode = (rowData: any, column: any, rowIndex = 0, columnIndex =
rowIndex: rowIndex,
colIndex: columnIndex,
oldValue: rowData[column.dataKey],
dataType: dbDialect.getDataType(column.columnType),
};
};
@@ -745,6 +796,28 @@ const rowClass = (row: any) => {
return '';
};
/**
* 根据数据库返回的时间字段类型,获取格式化后的时间值
* @param dataType getDataType返回的数据类型
* @param originValue 原始值
* @return 格式化后的值
*/
const getFormatTimeValue = (dataType: DataType, originValue: string): string => {
if (!originValue || dataType === DataType.Number || dataType === DataType.String) {
return originValue;
}
switch (dataType) {
case DataType.Time:
return dateStrFormat('HH:mm:ss', originValue);
case DataType.Date:
return dateStrFormat('yyyy-MM-dd', originValue);
case DataType.DateTime:
return dateStrFormat('yyyy-MM-dd HH:mm:ss', originValue);
default:
return originValue;
}
};
const getColumnTip = (column: any) => {
const comment = column.columnComment;
return `${column.columnType} ${comment ? ' | ' + comment : ''}`;
@@ -812,5 +885,15 @@ defineExpose({
padding: 2px;
height: 12px;
}
.edit-time-picker {
height: 26px;
width: 100%;
.el-input__prefix {
display: none;
}
.el-input__inner {
text-align: center;
}
}
}
</style>

View File

@@ -183,6 +183,35 @@
class="w100"
/>
<el-date-picker
v-else-if="dbDialect.getDataType(column.columnType) === DataType.DateTime"
v-model="addDataDialog.data[`${column.columnName}`]"
:placeholder="`${column.columnType} ${column.columnComment}`"
type="datetime"
class="w100"
:default-value="new Date()"
:default-time="new Date()"
value-format="YYYY-MM-DD HH:mm:ss"
/>
<el-date-picker
v-else-if="dbDialect.getDataType(column.columnType) === DataType.Date"
v-model="addDataDialog.data[`${column.columnName}`]"
:placeholder="`${column.columnType} ${column.columnComment}`"
type="Date"
class="w100"
:default-value="new Date()"
value-format="YYYY-MM-DD"
/>
<el-time-picker
v-else-if="dbDialect.getDataType(column.columnType) === DataType.Time"
v-model="addDataDialog.data[`${column.columnName}`]"
:placeholder="`${column.columnType} ${column.columnComment}`"
type="Date"
class="w100"
:default-value="new Date()"
value-format="HH:mm:ss"
/>
<el-input v-else v-model="addDataDialog.data[`${column.columnName}`]" :placeholder="`${column.columnType} ${column.columnComment}`" />
</el-form-item>
</el-form>
@@ -203,6 +232,7 @@ import { ElMessage } from 'element-plus';
import { DbInst } from '@/views/ops/db/db';
import DbTableData from './DbTableData.vue';
import { DataType, DbDialect, getDbDialect } from '@/views/ops/db/dialect';
const props = defineProps({
dbId: {
@@ -270,9 +300,10 @@ const state = reactive({
},
tableHeight: '600px',
hasUpdatedFileds: false,
dbDialect: {} as DbDialect,
});
const { datas, condition, loading, columns, pageNum, pageSize, pageSizes, count, hasUpdatedFileds, conditionDialog, addDataDialog } = toRefs(state);
const { datas, condition, loading, columns, pageNum, pageSize, pageSizes, count, hasUpdatedFileds, conditionDialog, addDataDialog, dbDialect } = toRefs(state);
watch(
() => props.tableHeight,
@@ -288,7 +319,6 @@ const getNowDbInst = () => {
onMounted(async () => {
console.log('in table data mounted');
state.tableHeight = props.tableHeight;
const columns = await getNowDbInst().loadColumns(props.dbName, props.tableName);
columns.forEach((x: any) => {
x.show = true;
@@ -296,6 +326,8 @@ onMounted(async () => {
state.columns = columns;
await onRefresh();
state.dbDialect = getDbDialect(getNowDbInst().type);
// 点击除选择列按钮外,若存在条件弹窗,则关闭该弹窗
window.addEventListener('click', handlerWindowClick);
});

View File

@@ -373,15 +373,6 @@ export class DbInst {
return columnType.match(/int|double|float|nubmer|decimal|byte|bit/gi);
}
/**
* 判断字段类型是否为日期相关类型
* @param columnType 字段类型
* @returns
*/
static isDate(columnType: string) {
return columnType.match(/date|time/gi);
}
/**
*
* @param str 字符串

View File

@@ -1,5 +1,15 @@
import { DbInst } from '../db';
import { DbDialect, sqlColumnType, DialectInfo, RowDefinition, IndexDefinition, EditorCompletionItem, commonCustomKeywords, EditorCompletion } from './index';
import {
DbDialect,
sqlColumnType,
DialectInfo,
RowDefinition,
IndexDefinition,
EditorCompletionItem,
commonCustomKeywords,
EditorCompletion,
DataType,
} from './index';
import { language as sqlLanguage } from 'monaco-editor/esm/vs/basic-languages/sql/sql.js';
export { DMDialect, DM_TYPE_LIST };
@@ -435,16 +445,6 @@ class DMDialect implements DbDialect {
return name;
};
getShortColumnType(columnType: string): string {
if (DbInst.isNumber(columnType)) {
return '123';
}
if (DbInst.isDate(columnType)) {
return 'date';
}
return 'abc';
}
matchType(text: string, arr: string[]): boolean {
if (!text || !arr || arr.length === 0) {
return false;
@@ -615,4 +615,23 @@ class DMDialect implements DbDialect {
}
return '';
}
getDataType(columnType: string): DataType {
if (DbInst.isNumber(columnType)) {
return DataType.Number;
}
// 日期时间类型
if (/datetime|timestamp/gi.test(columnType)) {
return DataType.DateTime;
}
// 日期类型
if (/date/gi.test(columnType)) {
return DataType.Date;
}
// 时间类型
if (/time/gi.test(columnType)) {
return DataType.Time;
}
return DataType.String;
}
}

View File

@@ -52,6 +52,29 @@ export interface EditorCompletion {
variables: EditorCompletionItem[];
}
// 定义一个数据类型的枚举,包含字符串、数字、日期、时间、日期时间
export enum DataType {
String = 'string',
Number = 'number',
Date = 'date',
Time = 'time',
DateTime = 'datetime',
}
/** 列数据类型角标 */
export const ColumnTypeSubscript = {
/** 字符串 */
string: 'abc',
/** 数字 */
number: '123',
/** 日期 */
date: 'icon-clock',
/** 时间 */
time: 'icon-clock',
/** 日期时间 */
datetime: 'icon-clock',
};
// 数据库基础信息
export interface DialectInfo {
/**
@@ -106,12 +129,6 @@ export interface DbDialect {
getDefaultIndex(): IndexDefinition;
/**
* 根据数据库完整字段类型获取类型简称。如字符串为abc、数字为123、日期为date等。
* @param columnType 数据库原始字段类型
*/
getShortColumnType(columnType: string): string;
/**
* 包裹数据库表名、字段名等,避免使用关键字为字段名或表名时报错
* @param name 名称
@@ -143,6 +160,9 @@ export interface DbDialect {
* @param changeData 改变数据
*/
getModifyIndexSql(tableName: string, changeData: { del: any[]; add: any[]; upd: any[] }): string;
/** 通过数据库字段类型,返回基本数据类型 */
getDataType: (columnType: string) => DataType;
}
let mysqlDialect = new MysqlDialect();

View File

@@ -1,5 +1,5 @@
import { DbInst } from '../db';
import { commonCustomKeywords, DbDialect, DialectInfo, EditorCompletion, EditorCompletionItem, IndexDefinition, RowDefinition } from './index';
import { commonCustomKeywords, DataType, DbDialect, DialectInfo, EditorCompletion, EditorCompletionItem, IndexDefinition, RowDefinition } from './index';
import { language as mysqlLanguage } from 'monaco-editor/esm/vs/basic-languages/mysql/mysql.js';
export { MYSQL_TYPE_LIST, MysqlDialect };
@@ -179,16 +179,6 @@ class MysqlDialect implements DbDialect {
};
}
getShortColumnType(columnType: string): string {
if (DbInst.isNumber(columnType)) {
return '123';
}
if (DbInst.isDate(columnType)) {
return 'date';
}
return 'abc';
}
wrapName = (name: string) => {
return `\`${name}\``;
};
@@ -314,4 +304,23 @@ class MysqlDialect implements DbDialect {
}
return '';
}
getDataType(columnType: string): DataType {
if (DbInst.isNumber(columnType)) {
return DataType.Number;
}
// 日期时间类型
if (/datetime|timestamp/gi.test(columnType)) {
return DataType.DateTime;
}
// 日期类型
if (/date/gi.test(columnType)) {
return DataType.Date;
}
// 时间类型
if (/time/gi.test(columnType)) {
return DataType.Time;
}
return DataType.String;
}
}

View File

@@ -1,5 +1,15 @@
import { DbInst } from '../db';
import { commonCustomKeywords, DbDialect, DialectInfo, EditorCompletion, EditorCompletionItem, IndexDefinition, RowDefinition, sqlColumnType } from './index';
import {
commonCustomKeywords,
DataType,
DbDialect,
DialectInfo,
EditorCompletion,
EditorCompletionItem,
IndexDefinition,
RowDefinition,
sqlColumnType,
} from './index';
import { language as pgsqlLanguage } from 'monaco-editor/esm/vs/basic-languages/pgsql/pgsql.js';
export { PostgresqlDialect, GAUSS_TYPE_LIST };
@@ -190,16 +200,6 @@ class PostgresqlDialect implements DbDialect {
};
}
getShortColumnType(columnType: string): string {
if (DbInst.isNumber(columnType)) {
return '123';
}
if (DbInst.isDate(columnType)) {
return 'date';
}
return 'abc';
}
wrapName = (name: string) => {
return name;
};
@@ -382,4 +382,23 @@ class PostgresqlDialect implements DbDialect {
}
return '';
}
getDataType(columnType: string): DataType {
if (DbInst.isNumber(columnType)) {
return DataType.Number;
}
// 日期时间类型
if (/datetime|timestamp/gi.test(columnType)) {
return DataType.DateTime;
}
// 日期类型
if (/date/gi.test(columnType)) {
return DataType.Date;
}
// 时间类型
if (/time/gi.test(columnType)) {
return DataType.Time;
}
return DataType.String;
}
}