更新若干功能

This commit is contained in:
hero920103 committed 2026-10-21 17:45:50 +08:00
1 parent 892ba5886d
commit 79d5ae6b66
45 files changed
+6755 -38

No files matched your search

+2 -1
View File
@@ -4,7 +4,7 @@ import request from "@/utils/request";
* 小程序多应用管理
*/
/** 获取小程序应用列表(AppSecret 不回显,返回 configured 标记) */
/** 获取小程序应用列表(AppSecret 不回显,返回 configured 标记;含 qrcode_url) */
export function listMiniApps() {
return request({
url: "/platform/wechatMini/apps",
@@ -19,6 +19,7 @@ export function listMiniApps() {
* @param {string} data.name 应用名称
* @param {string} data.app_id 小程序 AppID
* @param {string} [data.app_secret] 掩码/空串 = 不修改原值
* @param {string} [data.qrcode_url] 小程序二维码图片地址(空串 = 清空)
* @param {number} data.enabled 1=启用 0=停用
* @param {number} data.auto_bind 1=手机号命中身份后自动绑定
* @param {string} [data.remark] 备注
@@ -48,6 +48,19 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="二维码" width="90" align="center">
<template #default="scope">
<el-image
v-if="scope.row.qrcode_url"
:src="previewUrl(scope.row.qrcode_url)"
:preview-src-list="[previewUrl(scope.row.qrcode_url)]"
preview-teleported
fit="contain"
style="width: 48px; height: 48px"
/>
<span v-else class="empty-tip">未上传</span>
</template>
</el-table-column>
<el-table-column label="启用" width="80" align="center">
<template #default="scope">
<el-switch
@@ -127,6 +140,46 @@
"
/>
</el-form-item>
<el-form-item label="小程序二维码">
<div class="qrcode-field">
<div v-if="form.qrcode_url" class="qrcode-preview">
<el-image
:src="previewUrl(form.qrcode_url)"
:preview-src-list="[previewUrl(form.qrcode_url)]"
preview-teleported
fit="contain"
style="width: 120px; height: 120px"
/>
<div class="qrcode-actions">
<el-upload
:show-file-list="false"
accept="image/jpeg,image/png,image/gif,image/webp,image/bmp"
:http-request="handleQrcodeUpload"
>
<el-button size="small" :loading="qrcodeUploading">重新上传</el-button>
</el-upload>
<el-button size="small" type="danger" plain @click="removeQrcode">
删除
</el-button>
</div>
</div>
<el-upload
v-else
:show-file-list="false"
accept="image/jpeg,image/png,image/gif,image/webp,image/bmp"
:http-request="handleQrcodeUpload"
>
<div class="qrcode-upload">
<el-icon><Plus /></el-icon>
<span>{{ qrcodeUploading ? "上传中..." : "上传二维码" }}</span>
</div>
</el-upload>
<div class="form-tip block">
建议上传小程序码原图(≤2MB)。保存后官网 / H5 等其他端可调用
<code>GET /site/miniapp</code> 获取该图片地址(qrcode_url)。
</div>
</div>
</el-form-item>
<el-form-item label="启用">
<el-switch v-model="form.enabled" :active-value="1" :inactive-value="0" />
<span class="form-tip">启用后小程序端才可使用微信一键登录</span>
@@ -161,9 +214,20 @@ import { ElMessage, ElMessageBox } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import { listMiniApps, saveMiniApp, deleteMiniApp } from "@/api/miniApp";
import { formatDateTime } from "@/utils/datetime";
import { smartUpload } from "@/utils/qiniuUpload";
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || "";
// 相对地址(/uploads/...)拼接接口域名,绝对地址原样使用
const previewUrl = (url) => {
if (!url) return "";
if (/^https?:\/\//i.test(url)) return url;
return API_BASE_URL + url;
};
const loading = ref(false);
const saving = ref(false);
const qrcodeUploading = ref(false);
const apps = ref([]);
const dialogVisible = ref(false);
const formRef = ref(null);
@@ -174,6 +238,7 @@ const emptyForm = () => ({
name: "",
app_id: "",
app_secret: "",
qrcode_url: "",
enabled: 0,
auto_bind: 1,
remark: "",
@@ -217,6 +282,7 @@ const openEdit = (row) => {
name: row.name || "",
app_id: row.app_id || "",
app_secret: "",
qrcode_url: row.qrcode_url || "",
enabled: row.enabled,
auto_bind: row.auto_bind,
remark: row.remark || "",
@@ -225,6 +291,38 @@ const openEdit = (row) => {
dialogVisible.value = true;
};
// 二维码上传:上传成功后先写入表单,保存时随应用一起落库
const handleQrcodeUpload = async ({ file, onSuccess, onError }) => {
const raw = file?.raw ?? file;
if (!raw) return;
if (!/^image\//.test(raw.type || "")) {
ElMessage.error("请选择图片文件");
onError?.(new Error("请选择图片文件"));
return;
}
if (raw.size > 2 * 1024 * 1024) {
ElMessage.error("二维码图片不能超过 2MB");
onError?.(new Error("二维码图片不能超过 2MB"));
return;
}
qrcodeUploading.value = true;
try {
const result = await smartUpload(raw);
form.value.qrcode_url = result.url || "";
ElMessage.success("二维码上传成功");
onSuccess?.(result);
} catch (error) {
ElMessage.error(error?.message || "二维码上传失败");
onError?.(error);
} finally {
qrcodeUploading.value = false;
}
};
const removeQrcode = () => {
form.value.qrcode_url = "";
};
const handleSave = () => {
formRef.value?.validate(async (valid) => {
if (!valid) return;
@@ -262,6 +360,7 @@ const quickToggle = async (row, field, val) => {
name: row.name,
app_id: row.app_id,
app_secret: "",
qrcode_url: row.qrcode_url || "",
enabled: field === "enabled" ? (val ? 1 : 0) : row.enabled,
auto_bind: field === "auto_bind" ? (val ? 1 : 0) : row.auto_bind,
remark: row.remark || "",
@@ -327,6 +426,69 @@ onMounted(() => {
margin-left: 10px;
color: #8a94ad;
font-size: 12px;
&.block {
display: block;
margin-left: 0;
margin-top: 8px;
line-height: 1.6;
}
code {
padding: 0 4px;
background: #f2f4f8;
border-radius: 3px;
color: #5a6478;
}
}
.empty-tip {
color: #b3bac9;
font-size: 12px;
}
.qrcode-field {
width: 100%;
}
.qrcode-preview {
display: flex;
align-items: flex-end;
gap: 12px;
.qrcode-actions {
display: flex;
flex-direction: column;
gap: 8px;
:deep(.el-upload) {
width: 100%;
}
:deep(.el-button) {
width: 100%;
margin-left: 0;
}
}
}
.qrcode-upload {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
width: 120px;
height: 120px;
border: 1px dashed #c8cfdd;
border-radius: 6px;
color: #8a94ad;
font-size: 12px;
&:hover {
border-color: var(--el-color-primary);
color: var(--el-color-primary);
}
}
}
</style>