mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-10-08 11:06:39 +08:00
更改view为抽屉展示,增加导出确认提示
This commit is contained in:
parent
70e9f966c3
commit
514a9a32b3
@ -9,6 +9,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
@ -21,18 +22,18 @@ func (l *gCurd) webViewTplData(ctx context.Context, in *CurdPreviewInput) (data
|
||||
func (l *gCurd) generateWebViewItem(ctx context.Context, in *CurdPreviewInput) string {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
for _, field := range in.masterFields {
|
||||
if !field.IsEdit {
|
||||
continue
|
||||
}
|
||||
// if !field.IsEdit {
|
||||
// continue
|
||||
// }
|
||||
|
||||
var (
|
||||
defaultComponent = fmt.Sprintf("<n-descriptions-item>\n <template #label>%s</template>\n {{ formValue.%s }}\n </n-descriptions-item>", field.Dc, field.TsName)
|
||||
defaultComponent = fmt.Sprintf(" <div class=\"item\">\n <div>%s:</div>\n <div class=\"value\">{{ params.%s }}</div>\n </div>", field.Dc, field.TsName)
|
||||
component string
|
||||
)
|
||||
|
||||
switch field.FormMode {
|
||||
case FormModeInputTextarea, FormModeInputEditor:
|
||||
component = fmt.Sprintf("<n-descriptions-item>\n <template #label>%s</template>\n <span v-html=\"formValue.%s\"></span></n-descriptions-item>", field.Dc, field.TsName)
|
||||
component = fmt.Sprintf(" <div class=\"item\">\n <div>%s:</div>\n <div class=\"value\">\n <span v-html=\"params.%s\"></span>\n </div>\n </div>", field.Dc, field.TsName)
|
||||
|
||||
case FormModeInputDynamic:
|
||||
component = defaultComponent
|
||||
@ -44,28 +45,28 @@ func (l *gCurd) generateWebViewItem(ctx context.Context, in *CurdPreviewInput) s
|
||||
component = defaultComponent
|
||||
|
||||
case FormModeRadio, FormModeSelect:
|
||||
component = fmt.Sprintf("<n-descriptions-item label=\"%s\">\n <n-tag\n :type=\"getOptionTag(options.%s, formValue?.%s)\"\n size=\"small\"\n class=\"min-left-space\"\n >{{ getOptionLabel(options.%s, formValue?.%s) }}</n-tag\n >\n </n-descriptions-item>", field.Dc, in.options.dictMap[field.TsName], field.TsName, in.options.dictMap[field.TsName], field.TsName)
|
||||
component = fmt.Sprintf(" <div class=\"item\">\n <div>%s:</div>\n <div class=\"value\">\n <n-tag\n :type=\"getOptionTag(options.%s, params?.%s)\"\n size=\"small\"\n class=\"min-left-space\"\n >{{ getOptionLabel(options.%s, params?.%s) }}</n-tag\n >\n </div>\n </div>", field.Dc, in.options.dictMap[field.TsName], field.TsName, in.options.dictMap[field.TsName], field.TsName)
|
||||
|
||||
case FormModeCheckbox, FormModeSelectMultiple:
|
||||
component = fmt.Sprintf("<n-descriptions-item label=\"%s\">\n <template v-for=\"(item, key) in formValue?.%s\" :key=\"key\">\n <n-tag\n :type=\"getOptionTag(options.%s, item)\"\n size=\"small\"\n class=\"min-left-space\"\n >{{ getOptionLabel(options.%s, item) }}</n-tag\n >\n </template>\n </n-descriptions-item>", field.Dc, field.TsName, in.options.dictMap[field.TsName], in.options.dictMap[field.TsName])
|
||||
component = fmt.Sprintf(" <div class=\"item\">\n <div>%s:</div>\n <div class=\"value\">\n <template v-for=\"(item, key) in params?.%s\" :key=\"key\">\n <n-tag\n :type=\"getOptionTag(options.%s, item)\"\n size=\"small\"\n class=\"min-left-space\"\n >{{ getOptionLabel(options.%s, item) }}\n </n-tag>\n </template>\n </div>\n </div>", field.Dc, field.TsName, in.options.dictMap[field.TsName], in.options.dictMap[field.TsName])
|
||||
|
||||
case FormModeUploadImage:
|
||||
component = fmt.Sprintf("<n-descriptions-item>\n <template #label>%s</template>\n <n-image style=\"margin-left: 10px; height: 100px; width: 100px\" :src=\"formValue.%s\"\n /></n-descriptions-item>", field.Dc, field.TsName)
|
||||
component = fmt.Sprintf(" <div class=\"item\">\n <div>%s:</div>\n <div class=\"value\">\n <n-image\n style=\"margin-left: 10px; height: 100px; width: 100px\"\n :src=\"params.%s\"\n />\n </div>\n </div>", field.Dc, field.TsName)
|
||||
|
||||
case FormModeUploadImages:
|
||||
component = fmt.Sprintf("<n-descriptions-item>\n <template #label>%s</template>\n <n-image-group>\n <n-space>\n <span v-for=\"(item, key) in formValue?.%s\" :key=\"key\">\n <n-image style=\"margin-left: 10px; height: 100px; width: 100px\" :src=\"item\" />\n </span>\n </n-space>\n </n-image-group>\n </n-descriptions-item>", field.Dc, field.TsName)
|
||||
component = fmt.Sprintf(" <div class=\"item\">\n <div>%s:</div>\n <div class=\"value\">\n <n-image-group>\n <n-space>\n <span v-for=\"(item, key) in params?.%s\" :key=\"key\">\n <n-image\n style=\"margin-left: 10px; height: 100px; width: 100px\"\n :src=\"item\"\n />\n </span>\n </n-space>\n </n-image-group>\n </div>\n </div>", field.Dc, field.TsName)
|
||||
|
||||
case FormModeUploadFile:
|
||||
component = fmt.Sprintf("<n-descriptions-item>\n <template #label>%s</template>\n <div\n class=\"upload-card\"\n v-show=\"formValue.%s !== ''\"\n @click=\"download(formValue.%s)\"\n >\n <div class=\"upload-card-item\" style=\"height: 100px; width: 100px\">\n <div class=\"upload-card-item-info\">\n <div class=\"img-box\">\n <n-avatar :style=\"fileAvatarCSS\">{{ getFileExt(formValue.%s) }}</n-avatar>\n </div>\n </div>\n </div>\n </div>\n </n-descriptions-item>", field.Dc, field.TsName, field.TsName, field.TsName)
|
||||
component = fmt.Sprintf(" <div class=\"item\">\n <div>%s:</div>\n <div class=\"value\"\n ><div\n class=\"upload-card\"\n v-show=\"params.attachfile !== ''\"\n @click=\"download(params.%s)\"\n >\n <div class=\"upload-card-item\" style=\"height: 100px; width: 100px\">\n <div class=\"upload-card-item-info\">\n <div class=\"img-box\">\n <n-avatar :style=\"fileAvatarCSS\">{{\n getFileExt(params.attachfile)\n }}</n-avatar>\n </div>\n </div>\n </div>\n </div></div\n >\n </div>", field.TsName, field.TsName)
|
||||
|
||||
case FormModeUploadFiles:
|
||||
component = fmt.Sprintf("<n-descriptions-item>\n <template #label>%s</template>\n <div class=\"upload-card\">\n <n-space style=\"gap: 0px 0px\">\n <div\n class=\"upload-card-item\"\n style=\"height: 100px; width: 100px\"\n v-for=\"(item, key) in formValue.%s\"\n :key=\"key\"\n >\n <div class=\"upload-card-item-info\">\n <div class=\"img-box\">\n <n-avatar :style=\"fileAvatarCSS\" @click=\"download(item)\">{{\n getFileExt(item)\n }}</n-avatar>\n </div>\n </div>\n </div>\n </n-space>\n </div>\n </n-descriptions-item>", field.Dc, field.TsName)
|
||||
component = fmt.Sprintf(" <div class=\"item\">\n <div>%s:</div>\n <div class=\"value\">\n <div class=\"upload-card\">\n <n-space style=\"gap: 0px 0px\">\n <div\n class=\"upload-card-item\"\n style=\"height: 100px; width: 100px\"\n v-for=\"(item, key) in params.%s\"\n :key=\"key\"\n >\n <div class=\"upload-card-item-info\">\n <div class=\"img-box\">\n <n-avatar :style=\"fileAvatarCSS\" @click=\"download(item)\">{{\n getFileExt(item)\n }}</n-avatar>\n </div>\n </div>\n </div>\n </n-space>\n </div>\n </div>\n </div>", field.Dc, field.TsName)
|
||||
|
||||
case FormModeSwitch:
|
||||
component = fmt.Sprintf("<n-descriptions-item label=\"%s\">\n <n-switch v-model:value=\"formValue.%s\" :unchecked-value=\"2\" :checked-value=\"1\" :disabled=\"true\"\n /></n-descriptions-item>", field.Dc, field.TsName)
|
||||
component = fmt.Sprintf(" <div class=\"item\">\n <div>%s:</div>\n <div class=\"value\">\n <n-switch\n v-model:value=\"params.%s\"\n :unchecked-value=\"2\"\n :checked-value=\"1\"\n :disabled=\"true\"\n />\n </div>\n </div>", field.Dc, field.TsName)
|
||||
|
||||
case FormModeRate:
|
||||
component = fmt.Sprintf("<n-descriptions-item label=\"%s\"\n ><n-rate readonly :default-value=\"formValue.%s\"\n /></n-descriptions-item>", field.Dc, field.TsName)
|
||||
component = fmt.Sprintf(" <div class=\"item\">\n <div>%s:</div>\n <div class=\"value\">\n <n-rate readonly :default-value=\"params.%s\" />\n </div>\n </div>", field.Dc, field.TsName)
|
||||
|
||||
default:
|
||||
component = defaultComponent
|
||||
|
@ -37,7 +37,7 @@ INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type
|
||||
SET @listId = LAST_INSERT_ID();
|
||||
@{ if or (eq .options.Step.HasView true) (eq .options.Step.HasEdit true) }
|
||||
-- 详情
|
||||
INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES (NULL, @dirId, '@{.tableComment}详情', '@{.varName | LcFirst}View', 'view/:id?', '', '2', '', '/@{.apiPrefix}/view', '', '/@{.componentPrefix}/view', '0', '@{.varName | LcFirst}Index', '0', '0', '', '0', '1', '0', '2', '', '20', '', '1', @now, @now);
|
||||
INSERT INTO `@{.menuTable}` (`id`, `pid`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `level`, `tree`, `sort`, `remark`, `status`, `created_at`, `updated_at`) VALUES (NULL, @listId, '@{.tableComment}详情', '@{.varName | LcFirst}View', 'view/:id?', '', '3', '', '/@{.apiPrefix}/view', '', '/@{.componentPrefix}/view', '0', '@{.varName | LcFirst}Index', '0', '0', '', '0', '1', '0', '2', '', '20', '', '1', @now, @now);
|
||||
@{end}
|
||||
|
||||
-- 菜单按钮
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="@{.tableComment}">
|
||||
<!-- 这是由系统生成的CURD表格,你可以将此行注释改为表格的描述 -->
|
||||
<!-- @{.tableComment}列表页 -->
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
@ -26,7 +26,6 @@
|
||||
:row-key="(row) => row.id"
|
||||
ref="actionRef"
|
||||
:actionColumn="actionColumn"
|
||||
:checked-row-keys="checkedIds"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
:scroll-x="1090"
|
||||
:resizeHeightOffset="-10000"
|
||||
@ -82,6 +81,7 @@
|
||||
:showModal="showModal"
|
||||
:formParams="formParams"
|
||||
/>@{end}
|
||||
@{ if eq .options.Step.HasView true } <View @updateShowView="updateShowView" :formParams="formParams" :showView="showView" />@{end}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -97,6 +97,8 @@
|
||||
@{ if or (eq .options.Step.HasView true) (eq .options.Step.HasEdit true) } import { useRouter } from 'vue-router';@{end}
|
||||
import { getOptionLabel } from '@/utils/hotgo';
|
||||
@{ if eq .options.Step.HasEdit true } import Edit from './edit.vue';@{end}
|
||||
@{ if eq .options.Step.HasView true } import View from './view.vue';@{end}
|
||||
|
||||
const { hasPermission } = usePermission();
|
||||
@{ if or (eq .options.Step.HasView true) (eq .options.Step.HasEdit true) } const router = useRouter();@{end}
|
||||
const actionRef = ref();
|
||||
@ -106,6 +108,7 @@
|
||||
const batchDeleteDisabled = ref(true);
|
||||
const checkedIds = ref([]);
|
||||
const showModal = ref(false);
|
||||
const showView = ref(false);
|
||||
const formParams = ref<State>();
|
||||
|
||||
const actionColumn = reactive({
|
||||
@ -189,7 +192,12 @@
|
||||
}
|
||||
@{ if eq .options.Step.HasView true }
|
||||
function handleView(record: Recordable) {
|
||||
router.push({ name: '@{.varName | LcFirst}View', params: { id: record.@{.pk.TsName} } });
|
||||
showView.value = true;
|
||||
formParams.value = newState(record as State);
|
||||
}
|
||||
|
||||
function updateShowView(value) {
|
||||
showView.value = value;
|
||||
}@{end}
|
||||
@{ if eq .options.Step.HasEdit true }
|
||||
function handleEdit(record: Recordable) {
|
||||
@ -223,8 +231,6 @@
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
Delete({ id: checkedIds.value }).then((_res) => {
|
||||
batchDeleteDisabled.value = true;
|
||||
checkedIds.value = [];
|
||||
message.success('删除成功');
|
||||
reloadTable();
|
||||
});
|
||||
@ -236,8 +242,19 @@
|
||||
}@{end}
|
||||
|
||||
@{ if eq .options.Step.HasExport true } function handleExport() {
|
||||
message.loading('正在导出列表...', { duration: 1200 });
|
||||
Export(searchFormRef.value?.formModel);
|
||||
dialog.warning({
|
||||
title: '警告',
|
||||
content: '是否确定执行此操作?',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
message.loading('正在导出列表...', { duration: 1200 });
|
||||
Export(searchFormRef.value?.formModel);
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}@{end}
|
||||
|
||||
@{ if eq .options.Step.HasStatus true } function handleStatus(record: Recordable, status: number) {
|
||||
|
@ -1,29 +1,35 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="@{.tableComment}详情"> <!-- CURD详情页--> </n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="proCard mt-4" size="small" :segmented="{ content: true }">
|
||||
<n-descriptions label-placement="left" class="py-2" column="4">
|
||||
<n-drawer v-model:show="isShowView" :width="502">
|
||||
<n-drawer-content title="@{.tableComment}详情">
|
||||
<div class="view">
|
||||
<div class="section">
|
||||
<div class="section-bd">
|
||||
@{.item}
|
||||
</n-descriptions>
|
||||
</n-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<n-button @click="closeView">关闭</n-button>
|
||||
</template>
|
||||
</n-drawer-content>
|
||||
</n-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { computed, watch, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { View } from '@{.importWebApi}';
|
||||
import { newState, options } from './model';
|
||||
import { newState, State, options } from './model';
|
||||
import { getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { getFileExt } from '@/utils/urlUtils';
|
||||
import { useDesignSetting } from '@/hooks/setting/useDesignSetting';
|
||||
|
||||
const { getAppTheme } = useDesignSetting();
|
||||
const message = useMessage();
|
||||
const router = useRouter();
|
||||
const id = Number(router.currentRoute.value.params.id);
|
||||
const formValue = ref(newState(null));
|
||||
const fileAvatarCSS = computed(() => {
|
||||
return {
|
||||
'--n-merged-size': `var(--n-avatar-size-override, 80px)`,
|
||||
@ -31,18 +37,95 @@
|
||||
};
|
||||
});
|
||||
|
||||
const emit = defineEmits(['updateShowView']);
|
||||
interface Props {
|
||||
showView: boolean;
|
||||
formParams?: State;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
showView: false,
|
||||
formParams: () => {
|
||||
return newState(null);
|
||||
},
|
||||
});
|
||||
|
||||
const isShowView = computed({
|
||||
get: () => {
|
||||
return props.showView;
|
||||
},
|
||||
set: (value) => {
|
||||
emit('updateShowView', value);
|
||||
},
|
||||
});
|
||||
|
||||
const viewLoading = ref(false);
|
||||
const params = ref<State>(props.formParams);
|
||||
|
||||
function closeView() {
|
||||
isShowView.value = false;
|
||||
}
|
||||
|
||||
//下载
|
||||
function download(url: string) {
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (id < 1) {
|
||||
message.error('@{.pk.Dc}不正确,请检查!');
|
||||
return;
|
||||
function loadForm(value) {
|
||||
viewLoading.value = true;
|
||||
View({ id: value.id })
|
||||
.then((res) => {
|
||||
params.value = res;
|
||||
})
|
||||
.finally(() => {
|
||||
viewLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.formParams,
|
||||
(value) => {
|
||||
console.log('watch数据:', value);
|
||||
loadForm(value);
|
||||
}
|
||||
formValue.value = await View({ @{.pk.TsName}: id });
|
||||
});
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
<style lang="less" scoped>
|
||||
.view {
|
||||
.section {
|
||||
padding: 5px 0;
|
||||
border-bottom: 1px dashed #eeeeee;
|
||||
|
||||
&-hd {
|
||||
padding-left: 10px;
|
||||
border-left: 3px solid v-bind(getAppTheme);
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
&-bd {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.item {
|
||||
flex: 0 0 calc((100% - 60px) / 1);
|
||||
display: flex;
|
||||
margin: 16px 30px 0 0;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
|
||||
&:nth-child(1n + 1) {
|
||||
margin: 16px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user