style(api): 统一代码格式化规范
- 调整 import 语句格式,统一空格和引号风格 - 修复函数参数跨行时的格式对齐问题 - 清理多余空行和注释中的空白字符 - 统一对象属性结尾逗号的使用规范 - 规范化字符串拼接和模板语法的格式 - 优化长参数列表的换行和缩进格式
This commit is contained in:
@@ -45,7 +45,7 @@
|
||||
|
||||
// 字典数据
|
||||
const data = getDictionaryOptions(props.dictCode);
|
||||
const content = ref<any>()
|
||||
const content = ref<any>();
|
||||
|
||||
/* 更新选中数据 */
|
||||
const updateValue = () => {
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref} from 'vue';
|
||||
import {listDictData} from "@/api/system/dict-data";
|
||||
import { ref } from 'vue';
|
||||
import { listDictData } from '@/api/system/dict-data';
|
||||
|
||||
const data = ref<any[]>([]);
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
);
|
||||
|
||||
// 字典数据
|
||||
listDictData({dictCode: props.dictCode}).then(res => {
|
||||
data.value = res.map(d => {
|
||||
listDictData({ dictCode: props.dictCode }).then((res) => {
|
||||
data.value = res.map((d) => {
|
||||
return {
|
||||
dictDataId: d.dictDataId,
|
||||
dictDataCode: d.dictDataCode,
|
||||
@@ -61,7 +61,10 @@
|
||||
const updateValue = (value: string) => {
|
||||
emit('update:value', value);
|
||||
emit('index', Number(props.index));
|
||||
emit('done', data.value.find(d => d.value === value))
|
||||
emit(
|
||||
'done',
|
||||
data.value.find((d) => d.value === value)
|
||||
);
|
||||
};
|
||||
|
||||
/* 失去焦点 */
|
||||
|
||||
@@ -10,16 +10,14 @@
|
||||
<div class="flex p-3 flex-col justify-center items-center">
|
||||
<ele-qr-code-svg :value="`${data}`" :size="260" />
|
||||
<span class="text-gray-400 py-3" @click="copyText(data)">{{ data }}</span>
|
||||
<span class="text-gray-500 text-lg">
|
||||
使用手机扫一扫
|
||||
</span>
|
||||
<span class="text-gray-500 text-lg"> 使用手机扫一扫 </span>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
||||
import {copyText} from "@/utils/common";
|
||||
import { CmsArticle } from '@/api/cms/cmsArticle/model';
|
||||
import { copyText } from '@/utils/common';
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<a-card title="二维码登录演示" :bordered="false">
|
||||
<div class="demo-content">
|
||||
<!-- 二维码登录组件 -->
|
||||
<QrLogin
|
||||
<QrLogin
|
||||
@loginSuccess="handleLoginSuccess"
|
||||
@loginError="handleLoginError"
|
||||
/>
|
||||
|
||||
|
||||
<!-- 演示控制面板 -->
|
||||
<div class="demo-controls">
|
||||
<h4>演示控制</h4>
|
||||
<a-space direction="vertical" style="width: 100%;">
|
||||
<a-space direction="vertical" style="width: 100%">
|
||||
<a-button @click="simulateScanned" type="primary" ghost>
|
||||
模拟扫码
|
||||
</a-button>
|
||||
@@ -21,12 +21,10 @@
|
||||
<a-button @click="simulateExpired" type="default">
|
||||
模拟过期
|
||||
</a-button>
|
||||
<a-button @click="simulateError" danger>
|
||||
模拟错误
|
||||
</a-button>
|
||||
<a-button @click="simulateError" danger> 模拟错误 </a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 状态显示 -->
|
||||
<div class="demo-status">
|
||||
<h4>当前状态</h4>
|
||||
@@ -46,12 +44,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
|
||||
<!-- 日志显示 -->
|
||||
<a-card title="操作日志" :bordered="false" style="margin-top: 16px;">
|
||||
<a-card title="操作日志" :bordered="false" style="margin-top: 16px">
|
||||
<div class="demo-logs">
|
||||
<div
|
||||
v-for="(log, index) in logs"
|
||||
<div
|
||||
v-for="(log, index) in logs"
|
||||
:key="index"
|
||||
class="log-item"
|
||||
:class="log.type"
|
||||
@@ -65,194 +63,197 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import QrLogin from './index.vue';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import QrLogin from './index.vue';
|
||||
|
||||
// 响应式数据
|
||||
const currentQrKey = ref<string>('');
|
||||
const currentStatus = ref<string>('loading');
|
||||
const remainingTime = ref<number>(300);
|
||||
const logs = ref<Array<{time: string, message: string, type: string}>>([]);
|
||||
// 响应式数据
|
||||
const currentQrKey = ref<string>('');
|
||||
const currentStatus = ref<string>('loading');
|
||||
const remainingTime = ref<number>(300);
|
||||
const logs = ref<Array<{ time: string; message: string; type: string }>>([]);
|
||||
|
||||
// 添加日志
|
||||
const addLog = (message: string, type: 'info' | 'success' | 'error' | 'warning' = 'info') => {
|
||||
const now = new Date();
|
||||
const time = now.toLocaleTimeString();
|
||||
logs.value.unshift({ time, message, type });
|
||||
|
||||
// 限制日志数量
|
||||
if (logs.value.length > 50) {
|
||||
logs.value = logs.value.slice(0, 50);
|
||||
}
|
||||
};
|
||||
// 添加日志
|
||||
const addLog = (
|
||||
message: string,
|
||||
type: 'info' | 'success' | 'error' | 'warning' = 'info'
|
||||
) => {
|
||||
const now = new Date();
|
||||
const time = now.toLocaleTimeString();
|
||||
logs.value.unshift({ time, message, type });
|
||||
|
||||
// 获取状态颜色
|
||||
const getStatusColor = (status: string) => {
|
||||
const colors = {
|
||||
loading: 'blue',
|
||||
active: 'green',
|
||||
scanned: 'orange',
|
||||
expired: 'red',
|
||||
error: 'red'
|
||||
// 限制日志数量
|
||||
if (logs.value.length > 50) {
|
||||
logs.value = logs.value.slice(0, 50);
|
||||
}
|
||||
};
|
||||
return colors[status] || 'default';
|
||||
};
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status: string) => {
|
||||
const texts = {
|
||||
loading: '正在生成',
|
||||
active: '等待扫码',
|
||||
scanned: '已扫码',
|
||||
expired: '已过期',
|
||||
error: '生成失败'
|
||||
// 获取状态颜色
|
||||
const getStatusColor = (status: string) => {
|
||||
const colors = {
|
||||
loading: 'blue',
|
||||
active: 'green',
|
||||
scanned: 'orange',
|
||||
expired: 'red',
|
||||
error: 'red'
|
||||
};
|
||||
return colors[status] || 'default';
|
||||
};
|
||||
return texts[status] || status;
|
||||
};
|
||||
|
||||
// 处理登录成功
|
||||
const handleLoginSuccess = (token: string) => {
|
||||
addLog(`登录成功,获得token: ${token.substring(0, 20)}...`, 'success');
|
||||
message.success('二维码登录成功!');
|
||||
};
|
||||
// 获取状态文本
|
||||
const getStatusText = (status: string) => {
|
||||
const texts = {
|
||||
loading: '正在生成',
|
||||
active: '等待扫码',
|
||||
scanned: '已扫码',
|
||||
expired: '已过期',
|
||||
error: '生成失败'
|
||||
};
|
||||
return texts[status] || status;
|
||||
};
|
||||
|
||||
// 处理登录错误
|
||||
const handleLoginError = (error: string) => {
|
||||
addLog(`登录失败: ${error}`, 'error');
|
||||
message.error(`登录失败: ${error}`);
|
||||
};
|
||||
// 处理登录成功
|
||||
const handleLoginSuccess = (token: string) => {
|
||||
addLog(`登录成功,获得token: ${token.substring(0, 20)}...`, 'success');
|
||||
message.success('二维码登录成功!');
|
||||
};
|
||||
|
||||
// 模拟扫码
|
||||
const simulateScanned = () => {
|
||||
currentStatus.value = 'scanned';
|
||||
addLog('模拟用户扫码', 'info');
|
||||
message.info('模拟扫码成功');
|
||||
};
|
||||
// 处理登录错误
|
||||
const handleLoginError = (error: string) => {
|
||||
addLog(`登录失败: ${error}`, 'error');
|
||||
message.error(`登录失败: ${error}`);
|
||||
};
|
||||
|
||||
// 模拟确认登录
|
||||
const simulateConfirmed = () => {
|
||||
const mockToken = 'mock_token_' + Date.now();
|
||||
handleLoginSuccess(mockToken);
|
||||
};
|
||||
// 模拟扫码
|
||||
const simulateScanned = () => {
|
||||
currentStatus.value = 'scanned';
|
||||
addLog('模拟用户扫码', 'info');
|
||||
message.info('模拟扫码成功');
|
||||
};
|
||||
|
||||
// 模拟过期
|
||||
const simulateExpired = () => {
|
||||
currentStatus.value = 'expired';
|
||||
remainingTime.value = 0;
|
||||
addLog('模拟二维码过期', 'warning');
|
||||
message.warning('二维码已过期');
|
||||
};
|
||||
// 模拟确认登录
|
||||
const simulateConfirmed = () => {
|
||||
const mockToken = 'mock_token_' + Date.now();
|
||||
handleLoginSuccess(mockToken);
|
||||
};
|
||||
|
||||
// 模拟错误
|
||||
const simulateError = () => {
|
||||
currentStatus.value = 'error';
|
||||
addLog('模拟生成二维码失败', 'error');
|
||||
handleLoginError('网络连接失败');
|
||||
};
|
||||
// 模拟过期
|
||||
const simulateExpired = () => {
|
||||
currentStatus.value = 'expired';
|
||||
remainingTime.value = 0;
|
||||
addLog('模拟二维码过期', 'warning');
|
||||
message.warning('二维码已过期');
|
||||
};
|
||||
|
||||
// 组件挂载
|
||||
onMounted(() => {
|
||||
addLog('二维码登录演示组件已加载', 'info');
|
||||
|
||||
// 模拟生成二维码
|
||||
setTimeout(() => {
|
||||
currentQrKey.value = 'demo_qr_' + Date.now();
|
||||
currentStatus.value = 'active';
|
||||
addLog(`生成二维码成功,Key: ${currentQrKey.value}`, 'success');
|
||||
|
||||
// 开始倒计时
|
||||
const timer = setInterval(() => {
|
||||
if (remainingTime.value > 0) {
|
||||
remainingTime.value--;
|
||||
} else {
|
||||
clearInterval(timer);
|
||||
if (currentStatus.value === 'active') {
|
||||
simulateExpired();
|
||||
// 模拟错误
|
||||
const simulateError = () => {
|
||||
currentStatus.value = 'error';
|
||||
addLog('模拟生成二维码失败', 'error');
|
||||
handleLoginError('网络连接失败');
|
||||
};
|
||||
|
||||
// 组件挂载
|
||||
onMounted(() => {
|
||||
addLog('二维码登录演示组件已加载', 'info');
|
||||
|
||||
// 模拟生成二维码
|
||||
setTimeout(() => {
|
||||
currentQrKey.value = 'demo_qr_' + Date.now();
|
||||
currentStatus.value = 'active';
|
||||
addLog(`生成二维码成功,Key: ${currentQrKey.value}`, 'success');
|
||||
|
||||
// 开始倒计时
|
||||
const timer = setInterval(() => {
|
||||
if (remainingTime.value > 0) {
|
||||
remainingTime.value--;
|
||||
} else {
|
||||
clearInterval(timer);
|
||||
if (currentStatus.value === 'active') {
|
||||
simulateExpired();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
}, 1000);
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.qr-login-demo {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
.qr-login-demo {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.demo-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 200px 200px;
|
||||
gap: 24px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.demo-controls {
|
||||
h4 {
|
||||
margin-bottom: 12px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-status {
|
||||
h4 {
|
||||
margin-bottom: 12px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-logs {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.log-item {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.log-time {
|
||||
color: #999;
|
||||
margin-right: 8px;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.log-message {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&.info .log-message {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
&.success .log-message {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.error .log-message {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
&.warning .log-message {
|
||||
color: #faad14;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.demo-content {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 16px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 200px 200px;
|
||||
gap: 24px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.demo-controls {
|
||||
h4 {
|
||||
margin-bottom: 12px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-status {
|
||||
h4 {
|
||||
margin-bottom: 12px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-logs {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.log-item {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.log-time {
|
||||
color: #999;
|
||||
margin-right: 8px;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.log-message {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&.info .log-message {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
&.success .log-message {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.error .log-message {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
&.warning .log-message {
|
||||
color: #faad14;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.demo-content {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,22 +7,29 @@
|
||||
<p class="loading-text">正在生成二维码...</p>
|
||||
</div>
|
||||
|
||||
<div v-else-if="qrCodeStatus === 'active'" class="qr-active cursor-pointer">
|
||||
<ele-qr-code-svg :value="qrCodeData" :size="200" @click="refreshQrCode" />
|
||||
<div
|
||||
v-else-if="qrCodeStatus === 'active'"
|
||||
class="qr-active cursor-pointer"
|
||||
>
|
||||
<ele-qr-code-svg
|
||||
:value="qrCodeData"
|
||||
:size="200"
|
||||
@click="refreshQrCode"
|
||||
/>
|
||||
<p class="qr-tip">请使用手机APP或小程序扫码登录</p>
|
||||
<p class="qr-expire-tip">二维码有效期:{{ formatTime(expireTime) }}</p>
|
||||
</div>
|
||||
|
||||
<div v-else-if="qrCodeStatus === 'scanned'" class="qr-scanned">
|
||||
<div class="scanned-icon">
|
||||
<CheckCircleOutlined style="font-size: 48px; color: #52c41a;" />
|
||||
<CheckCircleOutlined style="font-size: 48px; color: #52c41a" />
|
||||
</div>
|
||||
<p class="scanned-text">扫码成功,请在手机上确认登录</p>
|
||||
</div>
|
||||
|
||||
<div v-else-if="qrCodeStatus === 'expired'" class="qr-expired">
|
||||
<div class="expired-icon">
|
||||
<ClockCircleOutlined style="font-size: 48px; color: #ff4d4f;" />
|
||||
<ClockCircleOutlined style="font-size: 48px; color: #ff4d4f" />
|
||||
</div>
|
||||
<p class="expired-text">二维码已过期</p>
|
||||
<a-button type="primary" @click="refreshQrCode">刷新二维码</a-button>
|
||||
@@ -30,7 +37,7 @@
|
||||
|
||||
<div v-else-if="qrCodeStatus === 'error'" class="qr-error">
|
||||
<div class="error-icon">
|
||||
<ExclamationCircleOutlined style="font-size: 48px; color: #ff4d4f;" />
|
||||
<ExclamationCircleOutlined style="font-size: 48px; color: #ff4d4f" />
|
||||
</div>
|
||||
<p class="error-text">{{ errorMessage || '生成二维码失败' }}</p>
|
||||
<a-button type="primary" @click="refreshQrCode">重新生成</a-button>
|
||||
@@ -47,266 +54,272 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, onUnmounted, computed } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import {
|
||||
CheckCircleOutlined,
|
||||
ClockCircleOutlined,
|
||||
ExclamationCircleOutlined,
|
||||
ReloadOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import {generateQrCode, checkQrCodeStatus, type QrCodeResponse, QrCodeStatusResponse} from '@/api/passport/qrLogin';
|
||||
import { ref, onMounted, onUnmounted, computed } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import {
|
||||
CheckCircleOutlined,
|
||||
ClockCircleOutlined,
|
||||
ExclamationCircleOutlined,
|
||||
ReloadOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import {
|
||||
generateQrCode,
|
||||
checkQrCodeStatus,
|
||||
type QrCodeResponse,
|
||||
QrCodeStatusResponse
|
||||
} from '@/api/passport/qrLogin';
|
||||
|
||||
// 定义组件事件
|
||||
const emit = defineEmits<{
|
||||
(e: 'loginSuccess', data: QrCodeStatusResponse): void;
|
||||
(e: 'loginError', error: string): void;
|
||||
}>();
|
||||
// 定义组件事件
|
||||
const emit = defineEmits<{
|
||||
(e: 'loginSuccess', data: QrCodeStatusResponse): void;
|
||||
(e: 'loginError', error: string): void;
|
||||
}>();
|
||||
|
||||
// 响应式数据
|
||||
const qrCodeData = ref<string>('');
|
||||
const qrCodeToken = ref<string>('');
|
||||
const qrCodeStatus = ref<'loading' | 'active' | 'scanned' | 'expired' | 'error'>('loading');
|
||||
const expireTime = ref<number>(0);
|
||||
const errorMessage = ref<string>('');
|
||||
const refreshing = ref<boolean>(false);
|
||||
// 响应式数据
|
||||
const qrCodeData = ref<string>('');
|
||||
const qrCodeToken = ref<string>('');
|
||||
const qrCodeStatus = ref<
|
||||
'loading' | 'active' | 'scanned' | 'expired' | 'error'
|
||||
>('loading');
|
||||
const expireTime = ref<number>(0);
|
||||
const errorMessage = ref<string>('');
|
||||
const refreshing = ref<boolean>(false);
|
||||
|
||||
// 定时器
|
||||
let statusCheckTimer: number | null = null;
|
||||
let expireTimer: number | null = null;
|
||||
// 定时器
|
||||
let statusCheckTimer: number | null = null;
|
||||
let expireTimer: number | null = null;
|
||||
|
||||
// 计算属性:格式化剩余时间
|
||||
const formatTime = computed(() => {
|
||||
return (seconds: number) => {
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const remainingSeconds = seconds % 60;
|
||||
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
|
||||
};
|
||||
});
|
||||
// 计算属性:格式化剩余时间
|
||||
const formatTime = computed(() => {
|
||||
return (seconds: number) => {
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const remainingSeconds = seconds % 60;
|
||||
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* 生成二维码
|
||||
*/
|
||||
const generateQrCodeData = async () => {
|
||||
try {
|
||||
qrCodeStatus.value = 'loading';
|
||||
const response: QrCodeResponse = await generateQrCode();
|
||||
|
||||
// 后端返回的qrCode是二维码内容,我们需要构造完整的URL
|
||||
const baseUrl = window.location.origin;
|
||||
const qrCodeUrl = `${baseUrl}/qr-confirm?qrCodeKey=${response.token}`;
|
||||
|
||||
qrCodeData.value = qrCodeUrl;
|
||||
qrCodeToken.value = response.token;
|
||||
qrCodeStatus.value = 'active';
|
||||
expireTime.value = response.expiresIn || 300; // 默认5分钟过期
|
||||
|
||||
// 开始检查二维码状态
|
||||
startStatusCheck();
|
||||
// 开始倒计时
|
||||
startExpireCountdown();
|
||||
|
||||
} catch (error: any) {
|
||||
qrCodeStatus.value = 'error';
|
||||
errorMessage.value = error.message || '生成二维码失败';
|
||||
message.error(errorMessage.value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 开始检查二维码状态
|
||||
*/
|
||||
const startStatusCheck = () => {
|
||||
if (statusCheckTimer) {
|
||||
clearInterval(statusCheckTimer);
|
||||
}
|
||||
|
||||
statusCheckTimer = window.setInterval(async () => {
|
||||
/**
|
||||
* 生成二维码
|
||||
*/
|
||||
const generateQrCodeData = async () => {
|
||||
try {
|
||||
const status = await checkQrCodeStatus(qrCodeToken.value);
|
||||
qrCodeStatus.value = 'loading';
|
||||
const response: QrCodeResponse = await generateQrCode();
|
||||
|
||||
switch (status.status) {
|
||||
case 'scanned':
|
||||
qrCodeStatus.value = 'scanned';
|
||||
break;
|
||||
case 'confirmed':
|
||||
// 登录成功
|
||||
if(status.tenantId){
|
||||
localStorage.setItem('TenantId', `${status.tenantId}`)
|
||||
}
|
||||
qrCodeStatus.value = 'active';
|
||||
stopAllTimers();
|
||||
emit('loginSuccess', status);
|
||||
break;
|
||||
case 'expired':
|
||||
qrCodeStatus.value = 'expired';
|
||||
stopAllTimers();
|
||||
break;
|
||||
case 'pending':
|
||||
// 继续等待
|
||||
break;
|
||||
}
|
||||
// 后端返回的qrCode是二维码内容,我们需要构造完整的URL
|
||||
const baseUrl = window.location.origin;
|
||||
const qrCodeUrl = `${baseUrl}/qr-confirm?qrCodeKey=${response.token}`;
|
||||
|
||||
// 更新剩余时间
|
||||
if (status.expiresIn !== undefined) {
|
||||
expireTime.value = status.expiresIn;
|
||||
}
|
||||
qrCodeData.value = qrCodeUrl;
|
||||
qrCodeToken.value = response.token;
|
||||
qrCodeStatus.value = 'active';
|
||||
expireTime.value = response.expiresIn || 300; // 默认5分钟过期
|
||||
|
||||
// 开始检查二维码状态
|
||||
startStatusCheck();
|
||||
// 开始倒计时
|
||||
startExpireCountdown();
|
||||
} catch (error: any) {
|
||||
console.error('检查二维码状态失败:', error);
|
||||
// 继续检查,不中断流程
|
||||
qrCodeStatus.value = 'error';
|
||||
errorMessage.value = error.message || '生成二维码失败';
|
||||
message.error(errorMessage.value);
|
||||
}
|
||||
}, 2000); // 每2秒检查一次
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 开始过期倒计时
|
||||
*/
|
||||
const startExpireCountdown = () => {
|
||||
if (expireTimer) {
|
||||
clearInterval(expireTimer);
|
||||
}
|
||||
|
||||
expireTimer = window.setInterval(() => {
|
||||
if (expireTime.value <= 0) {
|
||||
qrCodeStatus.value = 'expired';
|
||||
stopAllTimers();
|
||||
return;
|
||||
/**
|
||||
* 开始检查二维码状态
|
||||
*/
|
||||
const startStatusCheck = () => {
|
||||
if (statusCheckTimer) {
|
||||
clearInterval(statusCheckTimer);
|
||||
}
|
||||
expireTime.value--;
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
/**
|
||||
* 停止所有定时器
|
||||
*/
|
||||
const stopAllTimers = () => {
|
||||
if (statusCheckTimer) {
|
||||
clearInterval(statusCheckTimer);
|
||||
statusCheckTimer = null;
|
||||
}
|
||||
if (expireTimer) {
|
||||
clearInterval(expireTimer);
|
||||
expireTimer = null;
|
||||
}
|
||||
};
|
||||
statusCheckTimer = window.setInterval(async () => {
|
||||
try {
|
||||
const status = await checkQrCodeStatus(qrCodeToken.value);
|
||||
|
||||
/**
|
||||
* 刷新二维码
|
||||
*/
|
||||
const refreshQrCode = async () => {
|
||||
refreshing.value = true;
|
||||
stopAllTimers();
|
||||
switch (status.status) {
|
||||
case 'scanned':
|
||||
qrCodeStatus.value = 'scanned';
|
||||
break;
|
||||
case 'confirmed':
|
||||
// 登录成功
|
||||
if (status.tenantId) {
|
||||
localStorage.setItem('TenantId', `${status.tenantId}`);
|
||||
}
|
||||
qrCodeStatus.value = 'active';
|
||||
stopAllTimers();
|
||||
emit('loginSuccess', status);
|
||||
break;
|
||||
case 'expired':
|
||||
qrCodeStatus.value = 'expired';
|
||||
stopAllTimers();
|
||||
break;
|
||||
case 'pending':
|
||||
// 继续等待
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
await generateQrCodeData();
|
||||
} finally {
|
||||
refreshing.value = false;
|
||||
}
|
||||
};
|
||||
// 更新剩余时间
|
||||
if (status.expiresIn !== undefined) {
|
||||
expireTime.value = status.expiresIn;
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('检查二维码状态失败:', error);
|
||||
// 继续检查,不中断流程
|
||||
}
|
||||
}, 2000); // 每2秒检查一次
|
||||
};
|
||||
|
||||
// 组件挂载时生成二维码
|
||||
onMounted(() => {
|
||||
generateQrCodeData();
|
||||
});
|
||||
/**
|
||||
* 开始过期倒计时
|
||||
*/
|
||||
const startExpireCountdown = () => {
|
||||
if (expireTimer) {
|
||||
clearInterval(expireTimer);
|
||||
}
|
||||
|
||||
// 组件卸载时清理定时器
|
||||
onUnmounted(() => {
|
||||
stopAllTimers();
|
||||
});
|
||||
expireTimer = window.setInterval(() => {
|
||||
if (expireTime.value <= 0) {
|
||||
qrCodeStatus.value = 'expired';
|
||||
stopAllTimers();
|
||||
return;
|
||||
}
|
||||
expireTime.value--;
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
/**
|
||||
* 停止所有定时器
|
||||
*/
|
||||
const stopAllTimers = () => {
|
||||
if (statusCheckTimer) {
|
||||
clearInterval(statusCheckTimer);
|
||||
statusCheckTimer = null;
|
||||
}
|
||||
if (expireTimer) {
|
||||
clearInterval(expireTimer);
|
||||
expireTimer = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 刷新二维码
|
||||
*/
|
||||
const refreshQrCode = async () => {
|
||||
refreshing.value = true;
|
||||
stopAllTimers();
|
||||
|
||||
try {
|
||||
await generateQrCodeData();
|
||||
} finally {
|
||||
refreshing.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 组件挂载时生成二维码
|
||||
onMounted(() => {
|
||||
generateQrCodeData();
|
||||
});
|
||||
|
||||
// 组件卸载时清理定时器
|
||||
onUnmounted(() => {
|
||||
stopAllTimers();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.qr-login-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.qr-code-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 250px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.qr-loading {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
|
||||
.loading-text {
|
||||
color: #666;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.qr-active {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
.qr-tip {
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
.qr-login-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.qr-expire-tip {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
.qr-code-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 250px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.qr-scanned {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
.qr-loading {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
|
||||
.scanned-text {
|
||||
color: #52c41a;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
.loading-text {
|
||||
color: #666;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.qr-expired {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
.qr-active {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
.expired-text {
|
||||
color: #ff4d4f;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
.qr-tip {
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.qr-expire-tip {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.qr-error {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
.qr-scanned {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
|
||||
.error-text {
|
||||
color: #ff4d4f;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
.scanned-text {
|
||||
color: #52c41a;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.qr-actions {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.qr-expired {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
|
||||
.expired-text {
|
||||
color: #ff4d4f;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.qr-error {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
|
||||
.error-text {
|
||||
color: #ff4d4f;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.qr-actions {
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { CmsDesign } from '@/api/cms/cmsDesign/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { CmsDesign } from '@/api/cms/Cmsdesign/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
@@ -46,7 +46,7 @@ const props = withDefaults(
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<CmsDesign | null>(null);
|
||||
const content = ref<any>(props.value)
|
||||
const content = ref<any>(props.value);
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: CmsDesign) => {
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'name'">
|
||||
<div class="cursor-pointer" @click="onRadio(record)">{{ record.name }}</div>
|
||||
<div class="cursor-pointer" @click="onRadio(record)">{{
|
||||
record.name
|
||||
}}</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<template v-if="pageId == record.pageId">
|
||||
@@ -118,7 +120,7 @@
|
||||
};
|
||||
|
||||
const onRadio = (record: CmsDesign) => {
|
||||
pageId.value = Number(record.pageId)
|
||||
pageId.value = Number(record.pageId);
|
||||
updateVisible(false);
|
||||
emit('done', record);
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { CmsDesign } from '@/api/cms/cmsDesign/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
}
|
||||
);
|
||||
|
||||
const content = ref<any>(props.value)
|
||||
const content = ref<any>(props.value);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done', Dict): void;
|
||||
|
||||
@@ -47,8 +47,8 @@
|
||||
import { User, UserParam } from '@/api/system/user/model';
|
||||
import { EleProTable } from 'ele-admin-pro';
|
||||
import useSearch from '@/utils/use-search';
|
||||
import {pageHjmFence} from "@/api/hjm/hjmFence";
|
||||
import {HjmFenceParam} from "@/api/hjm/hjmFence/model";
|
||||
import { pageHjmFence } from '@/api/hjm/hjmFence';
|
||||
import { HjmFenceParam } from '@/api/hjm/hjmFence/model';
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/>
|
||||
<a-button @click="openEdit">
|
||||
<template #icon>
|
||||
<BulbOutlined class="ele-text-warning"/>
|
||||
<BulbOutlined class="ele-text-warning" />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-input-group>
|
||||
@@ -25,51 +25,50 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {BulbOutlined} from '@ant-design/icons-vue';
|
||||
import {ref, watch} from 'vue';
|
||||
import SelectData from './components/select-data.vue';
|
||||
import {HjmFence} from "@/api/hjm/hjmFence/model";
|
||||
import { BulbOutlined } from '@ant-design/icons-vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { HjmFence } from '@/api/hjm/hjmFence/model';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
organizationId?: number;
|
||||
}>(),
|
||||
{
|
||||
placeholder: '请选择'
|
||||
}
|
||||
);
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
organizationId?: number;
|
||||
}>(),
|
||||
{
|
||||
placeholder: '请选择'
|
||||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done', HjmFence): void;
|
||||
(e: 'clear'): void;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'done', HjmFence): void;
|
||||
(e: 'clear'): void;
|
||||
}>();
|
||||
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<HjmFence | null>(null);
|
||||
const content = ref<HjmFence>(props.value)
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<HjmFence | null>(null);
|
||||
const content = ref<HjmFence>(props.value);
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: HjmFence) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: HjmFence) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
|
||||
const onChange = (row?: HjmFence) => {
|
||||
emit('done', row);
|
||||
};
|
||||
// 查询租户列表
|
||||
// const appList = ref<App[] | undefined>([]);
|
||||
const onChange = (row?: HjmFence) => {
|
||||
emit('done', row);
|
||||
};
|
||||
// 查询租户列表
|
||||
// const appList = ref<App[] | undefined>([]);
|
||||
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(visible) => {
|
||||
content.value = visible;
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
watch(
|
||||
() => props.value,
|
||||
(visible) => {
|
||||
content.value = visible;
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
@@ -64,19 +64,12 @@
|
||||
@search="reload"
|
||||
@pressEnter="reload"
|
||||
/>
|
||||
<a-button
|
||||
type="text"
|
||||
@click="openUrl('/cms/photo/dict')"
|
||||
>管理分组</a-button
|
||||
<a-button type="text" @click="openUrl('/cms/photo/dict')"
|
||||
>管理分组</a-button
|
||||
>
|
||||
<a-alert
|
||||
message="双击行也可以选择"
|
||||
banner
|
||||
closable
|
||||
/>
|
||||
<a-alert message="双击行也可以选择" banner closable />
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
@@ -115,7 +108,7 @@
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-space>
|
||||
<!-- <a-radio @click="onRadio(record)" />-->
|
||||
<!-- <a-radio @click="onRadio(record)" />-->
|
||||
<a class="ele-text-success" @click="onRadio(record)">选择</a>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm
|
||||
@@ -140,13 +133,18 @@
|
||||
ColumnItem,
|
||||
DatasourceFunction
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import {pageFiles, removeFile, uploadOss, uploadOssByGroupId} from '@/api/system/file';
|
||||
import {
|
||||
pageFiles,
|
||||
removeFile,
|
||||
uploadOss,
|
||||
uploadOssByGroupId
|
||||
} from '@/api/system/file';
|
||||
import { EleProTable, messageLoading } from 'ele-admin-pro';
|
||||
import { FileRecord, FileRecordParam } from '@/api/system/file/model';
|
||||
import { EditOutlined, UploadOutlined } from '@ant-design/icons-vue';
|
||||
import { DictData } from '@/api/system/dict-data/model';
|
||||
import { pageDictData } from '@/api/system/dict-data';
|
||||
import {isImage, isMobileDevice, openUrl} from '@/utils/common';
|
||||
import { isImage, isMobileDevice, openUrl } from '@/utils/common';
|
||||
import { message } from 'ant-design-vue/es';
|
||||
import FileRecordEdit from './file-record-edit.vue';
|
||||
|
||||
@@ -232,10 +230,10 @@
|
||||
if (dictDataId.value) {
|
||||
where.groupId = dictDataId.value;
|
||||
}
|
||||
if(props.type == 'video'){
|
||||
if (props.type == 'video') {
|
||||
where.contentType = props.type;
|
||||
}
|
||||
if(props.type == 'image'){
|
||||
if (props.type == 'image') {
|
||||
where.contentType = props.type;
|
||||
}
|
||||
return pageFiles({
|
||||
@@ -341,7 +339,6 @@
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: FileRecord) => {
|
||||
return {
|
||||
@@ -353,10 +350,10 @@
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
updateVisible(false);
|
||||
if(!isMobileDevice()){
|
||||
if (!isMobileDevice()) {
|
||||
record.path = record.url || record.downloadUrl;
|
||||
}
|
||||
console.log(record,'rec......')
|
||||
console.log(record, 'rec......');
|
||||
emit('done', record);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,11 +44,15 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { PlusOutlined, CloseOutlined, YoutubeOutlined } from '@ant-design/icons-vue';
|
||||
import {
|
||||
PlusOutlined,
|
||||
CloseOutlined,
|
||||
YoutubeOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import { ref } from 'vue';
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { FileRecord } from '@/api/system/file/model';
|
||||
import { isImage } from "@/utils/common";
|
||||
import { isImage } from '@/utils/common';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { Form } from '@/api/cms/form/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { Grade } from '@/api/user/grade/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { Group } from '@/api/system/user-group/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
|
||||
@@ -55,7 +55,10 @@
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import { pageShopMerchant } from '@/api/shop/shopMerchant';
|
||||
import { EleProTable } from 'ele-admin-pro';
|
||||
import { ShopMerchant, ShopMerchantParam } from '@/api/shop/shopMerchant/model';
|
||||
import {
|
||||
ShopMerchant,
|
||||
ShopMerchantParam
|
||||
} from '@/api/shop/shopMerchant/model';
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
@@ -99,7 +102,7 @@
|
||||
},
|
||||
{
|
||||
title: '商户类型',
|
||||
dataIndex: 'shopType',
|
||||
dataIndex: 'shopType'
|
||||
// key: 'shopType'
|
||||
},
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { ShopMerchant } from '@/api/shop/shopMerchant/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
customerType?: string;
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
const content = ref<string>(props.value)
|
||||
const content = ref<string>(props.value);
|
||||
// 当前编辑数据
|
||||
const current = ref<ShopMerchant | null>(null);
|
||||
|
||||
|
||||
@@ -61,8 +61,8 @@
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
import { EleProTable } from 'ele-admin-pro';
|
||||
import {pageCmsModel} from "@/api/cms/cmsModel";
|
||||
import {CmsModel, CmsModelParam} from "@/api/cms/cmsModel/model";
|
||||
import { pageCmsModel } from '@/api/cms/cmsModel';
|
||||
import { CmsModel, CmsModelParam } from '@/api/cms/cmsModel/model';
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { Company } from '@/api/system/company/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
customerType?: string;
|
||||
@@ -46,7 +46,7 @@ const props = withDefaults(
|
||||
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
const content = ref<any>(props.value)
|
||||
const content = ref<any>(props.value);
|
||||
// 当前编辑数据
|
||||
const current = ref<Company | null>(null);
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { Environment } from '@/api/system/environment/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
@@ -46,7 +46,7 @@ const props = withDefaults(
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<Environment | null>(null);
|
||||
const content = ref<any>(props.value)
|
||||
const content = ref<any>(props.value);
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Environment) => {
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { CmsMpPages } from '@/api/cms/cmsMpPages/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
@@ -46,7 +46,7 @@ const props = withDefaults(
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<CmsMpPages | null>(null);
|
||||
const page = ref<any>()
|
||||
const page = ref<any>();
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: CmsMpPages) => {
|
||||
|
||||
@@ -62,7 +62,10 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { listCmsNavigation, pageCmsNavigation } from '@/api/cms/cmsNavigation';
|
||||
import {
|
||||
listCmsNavigation,
|
||||
pageCmsNavigation
|
||||
} from '@/api/cms/cmsNavigation';
|
||||
import { EleProTable } from 'ele-admin-pro';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { toTreeData, eachTreeData } from 'ele-admin-pro/es';
|
||||
@@ -71,7 +74,10 @@
|
||||
ColumnItem,
|
||||
EleProTableDone
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import type { CmsNavigation, CmsNavigationParam } from '@/api/cms/cmsNavigation/model';
|
||||
import type {
|
||||
CmsNavigation,
|
||||
CmsNavigationParam
|
||||
} from '@/api/cms/cmsNavigation/model';
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import type { CmsNavigation } from '@/api/cms/cmsNavigation/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { Organization } from '@/api/system/organization/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
@@ -46,7 +46,7 @@ const props = withDefaults(
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<Organization | null>(null);
|
||||
const content = ref<any>(props.value)
|
||||
const content = ref<any>(props.value);
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Organization) => {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { Grade } from '@/api/user/grade/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
type?: string;
|
||||
@@ -48,7 +48,7 @@ const props = withDefaults(
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<Grade | null>(null);
|
||||
const content = ref<any>(props.value)
|
||||
const content = ref<any>(props.value);
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Grade) => {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { Spec } from '@/api/shop/spec/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
customerType?: string;
|
||||
@@ -48,7 +48,7 @@ const props = withDefaults(
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<Spec | null>(null);
|
||||
const content = ref<any>(props.value)
|
||||
const content = ref<any>(props.value);
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Spec) => {
|
||||
|
||||
@@ -54,11 +54,11 @@
|
||||
|
||||
const onChange = (value: any) => {
|
||||
console.log(value);
|
||||
data.value.map(d => {
|
||||
if(d.value == value){
|
||||
emit('done',d, Number(props.index))
|
||||
data.value.map((d) => {
|
||||
if (d.value == value) {
|
||||
emit('done', d, Number(props.index));
|
||||
}
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
@@ -66,11 +66,11 @@
|
||||
(specId) => {
|
||||
if (specId) {
|
||||
listSpecValue({ specId }).then((list) => {
|
||||
data.value = list.map(v => {
|
||||
v.label = v.specValue
|
||||
v.value = v.specValue
|
||||
data.value = list.map((v) => {
|
||||
v.label = v.specValue;
|
||||
v.value = v.specValue;
|
||||
return v;
|
||||
})
|
||||
});
|
||||
});
|
||||
} else {
|
||||
data.value = [];
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<User | null>(null);
|
||||
const content = ref<any>()
|
||||
const content = ref<any>();
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: User) => {
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
DatasourceFunction
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import { EleProTable } from 'ele-admin-pro';
|
||||
import {User, UserParam} from "@/api/system/user/model";
|
||||
import {pageUsers} from "@/api/system/user";
|
||||
import { User, UserParam } from '@/api/system/user/model';
|
||||
import { pageUsers } from '@/api/system/user';
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
@@ -86,7 +86,7 @@
|
||||
title: '域名',
|
||||
dataIndex: 'domain',
|
||||
key: 'domain'
|
||||
},
|
||||
}
|
||||
// {
|
||||
// title: '状态',
|
||||
// dataIndex: 'status',
|
||||
@@ -97,7 +97,7 @@
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
|
||||
if(searchText.value){
|
||||
if (searchText.value) {
|
||||
where.keywords = searchText.value;
|
||||
}
|
||||
return pageUsers({
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-button @click="openEdit">
|
||||
<template #icon><BulbOutlined v-if="value > 20" class="ele-text-heading" /><BulbOutlined v-else class="ele-text-danger" /></template>
|
||||
<template #icon
|
||||
><BulbOutlined
|
||||
v-if="value > 20"
|
||||
class="ele-text-heading" /><BulbOutlined
|
||||
v-else
|
||||
class="ele-text-danger"
|
||||
/></template>
|
||||
</a-button>
|
||||
<!-- 选择弹窗 -->
|
||||
<SelectData
|
||||
@@ -18,9 +24,9 @@
|
||||
import { BulbOutlined } from '@ant-design/icons-vue';
|
||||
import { ref } from 'vue';
|
||||
import SelectData from './components/select-data.vue';
|
||||
import {User} from "@/api/system/user/model";
|
||||
import { User } from '@/api/system/user/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
customerType?: string;
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { User } from '@/api/system/user/model';
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
placeholder?: string;
|
||||
@@ -48,7 +48,7 @@ const props = withDefaults(
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<User | null>(null);
|
||||
const user = ref<User>(props.value)
|
||||
const user = ref<User>(props.value);
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: User) => {
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
<div class="ele-text-placeholder">{{ record.comments }}</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'value'">
|
||||
<a-image v-if="record.type === 1" :src="record.value" :width="120"/>
|
||||
<a-image v-if="record.type === 1" :src="record.value" :width="120" />
|
||||
<div v-else>{{ record.value }}</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'defaultValue'">
|
||||
<a-image v-if="record.type === 1" :src="record.value" :width="120"/>
|
||||
<a-image v-if="record.type === 1" :src="record.value" :width="120" />
|
||||
<div v-else>{{ record.value }}</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'comments'">
|
||||
@@ -46,7 +46,7 @@
|
||||
<template #content>
|
||||
{{ record.comments }}
|
||||
</template>
|
||||
<ExclamationCircleOutlined/>
|
||||
<ExclamationCircleOutlined />
|
||||
</a-popover>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
@@ -58,112 +58,112 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref} from 'vue';
|
||||
import {
|
||||
ColumnItem,
|
||||
DatasourceFunction
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
|
||||
import {EleProTable} from 'ele-admin-pro';
|
||||
import {Company, CompanyParam} from '@/api/system/company/model';
|
||||
import {CmsWebsiteField} from '@/api/cms/cmsWebsiteField/model';
|
||||
import {pageWebsiteField} from "@/api/system/website/field";
|
||||
import { ref } from 'vue';
|
||||
import {
|
||||
ColumnItem,
|
||||
DatasourceFunction
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
import { EleProTable } from 'ele-admin-pro';
|
||||
import { Company, CompanyParam } from '@/api/system/company/model';
|
||||
import { CmsWebsiteField } from '@/api/cms/cmsWebsiteField/model';
|
||||
import { pageWebsiteField } from '@/api/system/website/field';
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 标题
|
||||
title?: string;
|
||||
// 修改回显的数据
|
||||
data?: CmsWebsiteField | null;
|
||||
}>();
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 标题
|
||||
title?: string;
|
||||
// 修改回显的数据
|
||||
data?: CmsWebsiteField | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done', data: Company): void;
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'done', data: Company): void;
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
}>();
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit('update:visible', value);
|
||||
};
|
||||
|
||||
// 搜索内容
|
||||
const searchText = ref(null);
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
title: '参数名',
|
||||
dataIndex: 'name',
|
||||
width: 180,
|
||||
key: 'name'
|
||||
},
|
||||
{
|
||||
title: '默认值',
|
||||
width: 120,
|
||||
dataIndex: 'defaultValue',
|
||||
key: 'defaultValue'
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'comments',
|
||||
key: 'comments',
|
||||
width: 120,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '可设置范围',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: 'modifyRange'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 180,
|
||||
align: 'center',
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({page, limit, where, orders}) => {
|
||||
where = {};
|
||||
// 搜索条件
|
||||
if (searchText.value) {
|
||||
where.keywords = searchText.value;
|
||||
}
|
||||
return pageWebsiteField({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: CompanyParam) => {
|
||||
tableRef?.value?.reload({page: 1, where});
|
||||
};
|
||||
|
||||
const onRadio = (record: Company) => {
|
||||
updateVisible(false);
|
||||
emit('done', record);
|
||||
};
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: Company) => {
|
||||
return {
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
updateVisible(false);
|
||||
emit('done', record);
|
||||
}
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit('update:visible', value);
|
||||
};
|
||||
|
||||
// 搜索内容
|
||||
const searchText = ref(null);
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
title: '参数名',
|
||||
dataIndex: 'name',
|
||||
width: 180,
|
||||
key: 'name'
|
||||
},
|
||||
{
|
||||
title: '默认值',
|
||||
width: 120,
|
||||
dataIndex: 'defaultValue',
|
||||
key: 'defaultValue'
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'comments',
|
||||
key: 'comments',
|
||||
width: 120,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '可设置范围',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: 'modifyRange'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 180,
|
||||
align: 'center',
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
|
||||
where = {};
|
||||
// 搜索条件
|
||||
if (searchText.value) {
|
||||
where.keywords = searchText.value;
|
||||
}
|
||||
return pageWebsiteField({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: CompanyParam) => {
|
||||
tableRef?.value?.reload({ page: 1, where });
|
||||
};
|
||||
|
||||
const onRadio = (record: Company) => {
|
||||
updateVisible(false);
|
||||
emit('done', record);
|
||||
};
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: Company) => {
|
||||
return {
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
updateVisible(false);
|
||||
emit('done', record);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
</script>
|
||||
<style lang="less"></style>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/>
|
||||
<a-button @click="openEdit">
|
||||
<template #icon>
|
||||
<BulbOutlined class="ele-text-warning"/>
|
||||
<BulbOutlined class="ele-text-warning" />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-input-group>
|
||||
@@ -25,40 +25,40 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {BulbOutlined} from '@ant-design/icons-vue';
|
||||
import {ref} from 'vue';
|
||||
import SelectData from './components/select-data.vue';
|
||||
import {CmsWebsiteField} from "@/api/cms/cmsWebsiteField/model";
|
||||
import { BulbOutlined } from '@ant-design/icons-vue';
|
||||
import { ref } from 'vue';
|
||||
import SelectData from './components/select-data.vue';
|
||||
import { CmsWebsiteField } from '@/api/cms/cmsWebsiteField/model';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
customerType?: string;
|
||||
placeholder?: string;
|
||||
}>(),
|
||||
{
|
||||
placeholder: '请选择数据'
|
||||
}
|
||||
);
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: any;
|
||||
customerType?: string;
|
||||
placeholder?: string;
|
||||
}>(),
|
||||
{
|
||||
placeholder: '请选择数据'
|
||||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done', data: CmsWebsiteField): void;
|
||||
(e: 'clear'): void;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'done', data: CmsWebsiteField): void;
|
||||
(e: 'clear'): void;
|
||||
}>();
|
||||
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<CmsWebsiteField | null>(null);
|
||||
const content = ref<any>(props.value)
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 当前编辑数据
|
||||
const current = ref<CmsWebsiteField | null>(null);
|
||||
const content = ref<any>(props.value);
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: CmsWebsiteField) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: CmsWebsiteField) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
|
||||
const onChange = (item: CmsWebsiteField) => {
|
||||
emit('done', item);
|
||||
};
|
||||
const onChange = (item: CmsWebsiteField) => {
|
||||
emit('done', item);
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -83,11 +83,11 @@
|
||||
<span style="white-space: nowrap">{{ item.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <MpMenuEdit-->
|
||||
<!-- v-model:visible="showMpMenuEdit"-->
|
||||
<!-- :data="current"-->
|
||||
<!-- @done="reload"-->
|
||||
<!-- />-->
|
||||
<!-- <MpMenuEdit-->
|
||||
<!-- v-model:visible="showMpMenuEdit"-->
|
||||
<!-- :data="current"-->
|
||||
<!-- @done="reload"-->
|
||||
<!-- />-->
|
||||
</template>
|
||||
<!-- 商户列表 -->
|
||||
<template v-if="form.showShopCard">
|
||||
|
||||
@@ -276,11 +276,18 @@ export function setupTextIndent(editor: TinyMCEEditor) {
|
||||
|
||||
// 获取当前段落元素
|
||||
let paragraph = selectedNode;
|
||||
while (paragraph && paragraph.nodeName !== 'P' && paragraph.nodeName !== 'DIV') {
|
||||
while (
|
||||
paragraph &&
|
||||
paragraph.nodeName !== 'P' &&
|
||||
paragraph.nodeName !== 'DIV'
|
||||
) {
|
||||
paragraph = paragraph.parentNode as Element;
|
||||
}
|
||||
|
||||
if (paragraph && (paragraph.nodeName === 'P' || paragraph.nodeName === 'DIV')) {
|
||||
if (
|
||||
paragraph &&
|
||||
(paragraph.nodeName === 'P' || paragraph.nodeName === 'DIV')
|
||||
) {
|
||||
const currentIndent = (paragraph as HTMLElement).style.textIndent;
|
||||
|
||||
if (currentIndent === '2em' || currentIndent === '32px') {
|
||||
@@ -305,7 +312,11 @@ export function setupTextIndent(editor: TinyMCEEditor) {
|
||||
const content = selection.getContent();
|
||||
if (content) {
|
||||
// 如果有选择内容,将选择的内容包装在带缩进的段落中
|
||||
editor.execCommand('mceInsertContent', false, `<p style="text-indent: 2em;">${content}</p>`);
|
||||
editor.execCommand(
|
||||
'mceInsertContent',
|
||||
false,
|
||||
`<p style="text-indent: 2em;">${content}</p>`
|
||||
);
|
||||
} else {
|
||||
// 如果没有选择内容,在当前位置插入带缩进的段落
|
||||
editor.execCommand('FormatBlock', false, 'p');
|
||||
|
||||
Reference in New Issue
Block a user