|
@@ -0,0 +1,204 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="common-detail-props-editor">
|
|
|
|
|
+ <a-form :labelCol="{ span: 6 }" size="small">
|
|
|
|
|
+ <a-form-item label="测试内容ID">
|
|
|
|
|
+ <a-input-number
|
|
|
|
|
+ :value="testDetailId"
|
|
|
|
|
+ @update:value="emit('update:testDetailId', $event)"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ <a-collapse v-model:activeKey="activeKeys" class="props-collapse">
|
|
|
|
|
+ <a-collapse-panel key="articleBorrow" header="查询借阅功能 (articleBorrow)">
|
|
|
|
|
+ <a-form :labelCol="{ span: 6 }" size="small">
|
|
|
|
|
+ <a-form-item label="链接 URL">
|
|
|
|
|
+ <a-input v-model:value="articleBorrow.url" placeholder="借阅查询链接,支持 {title} 占位" />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ <a-form-item label="按钮文本">
|
|
|
|
|
+ <a-input v-model:value="articleBorrow.text" placeholder="如:点击查询借阅" />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ <a-form-item label="按钮图标">
|
|
|
|
|
+ <IconEditor v-model="articleBorrow.icon" />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ </a-form>
|
|
|
|
|
+ </a-collapse-panel>
|
|
|
|
|
+
|
|
|
|
|
+ <a-collapse-panel key="topButtons" header="顶部按钮 (topButtons)">
|
|
|
|
|
+ <div v-for="(item, i) in topButtonsList" :key="`btn-${i}`" class="nested-item">
|
|
|
|
|
+ <div class="item-actions">
|
|
|
|
|
+ <ArrowUpOutlined title="上移" @click.stop="moveTopButtonUp(i)" />
|
|
|
|
|
+ <ArrowDownOutlined title="下移" @click.stop="moveTopButtonDown(i)" />
|
|
|
|
|
+ <CopyOutlined title="复制" @click.stop="copyTopButton(i)" />
|
|
|
|
|
+ <a-popconfirm title="确定删除?" @confirm="removeTopButton(i)">
|
|
|
|
|
+ <a-button type="link" danger size="small">删除</a-button>
|
|
|
|
|
+ </a-popconfirm>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <a-form :labelCol="{ span: 6 }" size="small">
|
|
|
|
|
+ <a-form-item label="可见性表达式">
|
|
|
|
|
+ <a-input v-model:value="item.visible" placeholder="动态可见判断表达式" />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ <a-form-item label="按钮文本">
|
|
|
|
|
+ <a-input v-model:value="item.text" />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ <a-form-item label="按钮图标">
|
|
|
|
|
+ <IconEditor v-model="item.icon" />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ <a-form-item label="动作表达式">
|
|
|
|
|
+ <a-textarea v-model:value="item.expression" placeholder="点击执行的动作表达式" :auto-size="{ minRows: 1, maxRows: 4 }" />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ </a-form>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="section-footer">
|
|
|
|
|
+ <a-button type="dashed" block size="small" @click="addTopButton">+ 添加顶部按钮</a-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </a-collapse-panel>
|
|
|
|
|
+
|
|
|
|
|
+ <a-collapse-panel key="topShowInfos" header="顶部显示信息 (topShowInfos)">
|
|
|
|
|
+ <div v-for="(item, i) in topShowInfosList" :key="`info-${i}`" class="nested-item">
|
|
|
|
|
+ <div class="item-actions">
|
|
|
|
|
+ <ArrowUpOutlined title="上移" @click.stop="moveTopShowInfoUp(i)" />
|
|
|
|
|
+ <ArrowDownOutlined title="下移" @click.stop="moveTopShowInfoDown(i)" />
|
|
|
|
|
+ <CopyOutlined title="复制" @click.stop="copyTopShowInfo(i)" />
|
|
|
|
|
+ <a-popconfirm title="确定删除?" @confirm="removeTopShowInfo(i)">
|
|
|
|
|
+ <a-button type="link" danger size="small">删除</a-button>
|
|
|
|
|
+ </a-popconfirm>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <a-form :labelCol="{ span: 6 }" size="small">
|
|
|
|
|
+ <a-form-item label="数据键 key">
|
|
|
|
|
+ <a-input v-model:value="item.key" placeholder="显示信息数据键" />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ <a-form-item label="前缀文字">
|
|
|
|
|
+ <a-input v-model:value="item.prefix" placeholder="如:发布时间" />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ <a-form-item label="取值表达式">
|
|
|
|
|
+ <a-input v-model:value="item.expression" placeholder="表达式" />
|
|
|
|
|
+ </a-form-item>
|
|
|
|
|
+ </a-form>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="section-footer">
|
|
|
|
|
+ <a-button type="dashed" block size="small" @click="addTopShowInfo">+ 添加显示信息</a-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </a-collapse-panel>
|
|
|
|
|
+ </a-collapse>
|
|
|
|
|
+ </a-form>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import { ref, computed } from 'vue';
|
|
|
|
|
+import type { IHomeCommonArticleDetailDefine } from '../../defines/Details';
|
|
|
|
|
+import IconEditor from '../components/IconEditor.vue';
|
|
|
|
|
+import { ArrowUpOutlined, ArrowDownOutlined, CopyOutlined } from '@ant-design/icons-vue';
|
|
|
|
|
+import { ArrayUtils } from '@imengyu/imengyu-utils';
|
|
|
|
|
+import { message } from 'ant-design-vue';
|
|
|
|
|
+
|
|
|
|
|
+const props = defineProps<{
|
|
|
|
|
+ props: IHomeCommonArticleDetailDefine['props'];
|
|
|
|
|
+ testDetailId: number;
|
|
|
|
|
+}>();
|
|
|
|
|
+const emit = defineEmits<{
|
|
|
|
|
+ (e: 'update:testDetailId', value: number): void;
|
|
|
|
|
+}>();
|
|
|
|
|
+
|
|
|
|
|
+const activeKeys = ref<string[]>(['articleBorrow', 'topButtons', 'topShowInfos']);
|
|
|
|
|
+
|
|
|
|
|
+const articleBorrow = computed({
|
|
|
|
|
+ get() {
|
|
|
|
|
+ if (!props.props.articleBorrow) {
|
|
|
|
|
+ (props.props as Record<string, unknown>).articleBorrow = {
|
|
|
|
|
+ url: '',
|
|
|
|
|
+ text: '',
|
|
|
|
|
+ icon: '',
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ return props.props.articleBorrow!;
|
|
|
|
|
+ },
|
|
|
|
|
+ set(_) {
|
|
|
|
|
+ // 通过子字段 v-model 已直接写入 props.props.articleBorrow
|
|
|
|
|
+ },
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+const topButtonsList = computed(() => props.props?.topButtons ?? []);
|
|
|
|
|
+const topShowInfosList = computed(() => props.props?.topShowInfos ?? []);
|
|
|
|
|
+
|
|
|
|
|
+function getTopButtons() {
|
|
|
|
|
+ if (!props.props.topButtons) (props.props as Record<string, unknown>).topButtons = [];
|
|
|
|
|
+ return props.props.topButtons!;
|
|
|
|
|
+}
|
|
|
|
|
+function addTopButton() {
|
|
|
|
|
+ getTopButtons().push({
|
|
|
|
|
+ visible: '',
|
|
|
|
|
+ text: '',
|
|
|
|
|
+ icon: '',
|
|
|
|
|
+ expression: '',
|
|
|
|
|
+ });
|
|
|
|
|
+}
|
|
|
|
|
+function removeTopButton(i: number) {
|
|
|
|
|
+ getTopButtons().splice(i, 1);
|
|
|
|
|
+}
|
|
|
|
|
+function moveTopButtonUp(i: number) {
|
|
|
|
|
+ ArrayUtils.upData(getTopButtons(), i);
|
|
|
|
|
+}
|
|
|
|
|
+function moveTopButtonDown(i: number) {
|
|
|
|
|
+ ArrayUtils.downData(getTopButtons(), i);
|
|
|
|
|
+}
|
|
|
|
|
+function copyTopButton(i: number) {
|
|
|
|
|
+ const item = getTopButtons()[i];
|
|
|
|
|
+ uni.setClipboardData({
|
|
|
|
|
+ data: JSON.stringify({ type: 'Copy:CommonDetailTopButton', data: item }),
|
|
|
|
|
+ });
|
|
|
|
|
+ message.success('复制成功');
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function getTopShowInfos() {
|
|
|
|
|
+ if (!props.props.topShowInfos) (props.props as Record<string, unknown>).topShowInfos = [];
|
|
|
|
|
+ return props.props.topShowInfos!;
|
|
|
|
|
+}
|
|
|
|
|
+function addTopShowInfo() {
|
|
|
|
|
+ getTopShowInfos().push({
|
|
|
|
|
+ key: '',
|
|
|
|
|
+ prefix: '',
|
|
|
|
|
+ expression: '',
|
|
|
|
|
+ });
|
|
|
|
|
+}
|
|
|
|
|
+function removeTopShowInfo(i: number) {
|
|
|
|
|
+ getTopShowInfos().splice(i, 1);
|
|
|
|
|
+}
|
|
|
|
|
+function moveTopShowInfoUp(i: number) {
|
|
|
|
|
+ ArrayUtils.upData(getTopShowInfos(), i);
|
|
|
|
|
+}
|
|
|
|
|
+function moveTopShowInfoDown(i: number) {
|
|
|
|
|
+ ArrayUtils.downData(getTopShowInfos(), i);
|
|
|
|
|
+}
|
|
|
|
|
+function copyTopShowInfo(i: number) {
|
|
|
|
|
+ const item = getTopShowInfos()[i];
|
|
|
|
|
+ uni.setClipboardData({
|
|
|
|
|
+ data: JSON.stringify({ type: 'Copy:CommonDetailTopShowInfo', data: item }),
|
|
|
|
|
+ });
|
|
|
|
|
+ message.success('复制成功');
|
|
|
|
|
+}
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.common-detail-props-editor {
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+}
|
|
|
|
|
+.props-collapse {
|
|
|
|
|
+ margin-top: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+.nested-item {
|
|
|
|
|
+ margin-bottom: 12px;
|
|
|
|
|
+ padding: 8px;
|
|
|
|
|
+ background: #fafafa;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+}
|
|
|
|
|
+.item-actions {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: row;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+.section-footer {
|
|
|
|
|
+ margin-top: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|