@@ -361,6 +355,7 @@ import { useAuthStore } from '../stores/auth'
import { useUiStore } from '../stores/ui'
import { useDiaryStore } from '../stores/diary'
import { api } from '../composables/useApi'
+import { showConfirm } from '../composables/useDialog'
import { oilEn, recipeNameEn } from '../composables/useOilTranslation'
// TagPicker replaced with inline tag editing
@@ -481,6 +476,14 @@ async function loadBrand() {
} catch {
brand.value = {}
}
+ // Show upload prompt if user hasn't set up brand assets yet
+ if (showBrandHint.value) {
+ const ok = await showConfirm(
+ '上传你的专属二维码,让配方卡片更专业 ✨',
+ { okText: '去上传', cancelText: '取消' }
+ )
+ if (ok) goUploadQr()
+ }
}
// Whether to show the brand/QR upload hint (show to all users who haven't set up brand assets)
diff --git a/frontend/src/composables/useDialog.js b/frontend/src/composables/useDialog.js
index 1a43287..07688af 100644
--- a/frontend/src/composables/useDialog.js
+++ b/frontend/src/composables/useDialog.js
@@ -5,6 +5,8 @@ export const dialogState = reactive({
type: 'alert', // 'alert', 'confirm', 'prompt'
message: '',
defaultValue: '',
+ okText: '',
+ cancelText: '',
resolve: null
})
@@ -13,15 +15,19 @@ export function showAlert(msg) {
dialogState.visible = true
dialogState.type = 'alert'
dialogState.message = msg
+ dialogState.okText = ''
+ dialogState.cancelText = ''
dialogState.resolve = resolve
})
}
-export function showConfirm(msg) {
+export function showConfirm(msg, opts = {}) {
return new Promise(resolve => {
dialogState.visible = true
dialogState.type = 'confirm'
dialogState.message = msg
+ dialogState.okText = opts.okText || ''
+ dialogState.cancelText = opts.cancelText || ''
dialogState.resolve = resolve
})
}
diff --git a/frontend/src/views/MyDiary.vue b/frontend/src/views/MyDiary.vue
index cbe657e..95a5c60 100644
--- a/frontend/src/views/MyDiary.vue
+++ b/frontend/src/views/MyDiary.vue
@@ -107,6 +107,11 @@
+
+
+ 📋 上传完成后可返回配方卡片
+
+
🏷️ 品牌设置
@@ -232,6 +237,7 @@ const router = useRouter()
const activeTab = ref('brand')
const pasteText = ref('')
const selectedDiaryId = ref(null)
+const returnRecipeId = ref(null)
const selectedDiary = ref(null)
const newEntryText = ref('')
@@ -266,8 +272,16 @@ onMounted(async () => {
await diaryStore.loadDiary()
displayName.value = auth.user.display_name || ''
await loadBrandSettings()
+ returnRecipeId.value = localStorage.getItem('oil_return_recipe_id') || null
})
+function goBackToRecipe() {
+ if (returnRecipeId.value) {
+ localStorage.removeItem('oil_return_recipe_id')
+ router.push('/?openRecipe=' + encodeURIComponent(returnRecipeId.value))
+ }
+}
+
function selectDiary(d) {
const id = d._id || d.id
selectedDiaryId.value = id
@@ -755,6 +769,39 @@ async function applyBusiness() {
border-color: #7ec6a4;
}
+/* Return banner */
+.return-banner {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background: #f0faf5;
+ border: 1.5px solid #7ec6a4;
+ border-radius: 12px;
+ padding: 10px 14px;
+ margin-bottom: 14px;
+ font-size: 13px;
+ color: #3e7d5a;
+ gap: 10px;
+}
+
+.btn-return {
+ background: linear-gradient(135deg, #7ec6a4 0%, #4a9d7e 100%);
+ color: #fff;
+ border: none;
+ border-radius: 8px;
+ padding: 6px 14px;
+ font-size: 12px;
+ cursor: pointer;
+ font-family: inherit;
+ font-weight: 500;
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+
+.btn-return:hover {
+ opacity: 0.9;
+}
+
/* Brand */
.form-group {
margin-bottom: 14px;