Files
medical-mall/pages/mall/admin/maintain/lang/detail.uvue

335 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="admin-page">
<view class="admin-sections">
<!-- 搜索栏 -->
<view class="admin-card filter-card">
<view class="filter-row">
<view class="filter-item">
<text class="label">语言分类:</text>
<view class="filter-select">
<text class="select-text">页面语言</text>
<text class="arrow">▼</text>
</view>
</view>
<view class="filter-item">
<text class="label">语言类型:</text>
<view class="filter-select select-md">
<text class="select-text">中文(zh-CN)</text>
<text class="arrow">▼</text>
</view>
</view>
<view class="filter-item">
<text class="label">搜索:</text>
<input class="filter-input" placeholder="请输入语言备注" />
</view>
<button class="btn primary" @click="onSearch">搜索</button>
</view>
</view>
<!-- 提示栏 -->
<view class="alert-info">
<view class="info-block">
<text class="info-title">页面语言</text>
<text class="info-content">添加页面语言,添加完成之后状态码为中文文字,移动端面使用 $t('xxxx')js文件中使用 this.$t('xxxx') 或者使用 that.$t('xxxx') 实现语言的切换</text>
</view>
<view class="info-block mt-12">
<text class="info-title">接口语言</text>
<text class="info-content">添加接口语言添加完成之后状态码为6位数字接口返回提示信息时直接返回对应的错误码即可实现语言的切换</text>
</view>
</view>
<!-- 操作栏 -->
<view class="action-bar header-actions">
<button class="btn primary" @click="addWord">添加语句</button>
</view>
<!-- 表格内容 -->
<view class="admin-card content-card">
<view class="table-container list-table">
<view class="table-header">
<view class="col col-id"><text>编号</text></view>
<view class="col col-origin"><text>原语句</text></view>
<view class="col col-translation"><text>对应语言翻译</text></view>
<view class="col col-code"><text>状态码/文字(接口/页面调用参考)</text></view>
<view class="col col-type"><text>语言类型</text></view>
<view class="col col-action"><text>操作</text></view>
</view>
<view class="table-body">
<view v-for="item in pagedList" :key="item.id" class="table-row">
<view class="col col-id"><text>{{ item.id }}</text></view>
<view class="col col-origin"><text>{{ item.origin }}</text></view>
<view class="col col-translation"><text>{{ item.translation }}</text></view>
<view class="col col-code"><text>{{ item.code }}</text></view>
<view class="col col-type"><text>{{ item.type }}</text></view>
<view class="col col-action">
<text class="action-btn" @click="editWord(item)">编辑</text>
<text class="action-btn divider">|</text>
<text class="action-btn danger" @click="deleteWord(item)">删除</text>
</view>
</view>
</view>
</view>
<CommonPagination
v-if="true"
:total="total"
:loading="false"
:currentPage="currentPage"
:pageSize="pageSize"
:pageSizeOptionLabels="pageSizeOptionLabels"
:pageSizeIndex="pageSizeIndex"
:visiblePages="visiblePages"
:totalPage="totalPage"
:jumpPageInput="jumpPageInput"
@page-size-change="handlePageSizeChange"
@page-change="handlePageChange"
@update:jumpPageInput="(val: string) => { jumpPageInput.value = val }"
@jump-page="handleJumpPage"
/>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, computed } from 'vue'
import CommonPagination from '@/components/CommonPagination/CommonPagination.uvue'
// ========== MOCK DATA START ==========
// TODO: 接真实接口时替换此处 dataList 为 fetchTranslationList() 调用
const dataList = ref([
{ id: 55493, origin: '秒杀活动', translation: '秒杀活动', code: '秒杀活动', type: '中文(zh-CN)' },
{ id: 55483, origin: '哥哥我', translation: '', code: '哥哥我', type: '中文(zh-CN)' },
{ id: 25221, origin: '提交订单', translation: '提交订单', code: '提交订单', type: '中文(zh-CN)' },
{ id: 25211, origin: '用户等级优惠', translation: '用户等级优惠', code: '用户等级优惠', type: '中文(zh-CN)' },
{ id: 25201, origin: '暂不支付', translation: '暂不支付', code: '暂不支付', type: '中文(zh-CN)' },
{ id: 25191, origin: '确认支付', translation: '确认支付', code: '确认支付', type: '中文(zh-CN)' },
{ id: 25181, origin: '支付剩余时间', translation: '支付剩余时间', code: '支付剩余时间', type: '中文(zh-CN)' },
{ id: 24711, origin: '全部已读', translation: '全部已读', code: '全部已读', type: '中文(zh-CN)' },
{ id: 24701, origin: '获得拼团团长佣金', translation: '获得拼团团长佣金', code: '获得拼团团长佣金', type: '中文(zh-CN)' },
{ id: 24691, origin: '获得事业部推广订单佣金', translation: '获得事业部推广订单佣金', code: '获得事业部推广订单佣金', type: '中文(zh-CN)' },
{ id: 24681, origin: '返回默认地址', translation: '返回默认地址', code: '返回默认地址', type: '中文(zh-CN)' },
{ id: 24671, origin: '我的购物车', translation: '我的购物车', code: '我的购物车', type: '中文(zh-CN)' },
{ id: 24661, origin: '监控山东', translation: '监控山东', code: '监控山东', type: '中文(zh-CN)' },
{ id: 24651, origin: '商品评价', translation: '商品评价', code: '商品评价', type: '中文(zh-CN)' },
{ id: 24641, origin: '手机号已绑定', translation: '手机号已绑定', code: '手机号已绑定', type: '中文(zh-CN)' },
{ id: 24631, origin: '订单列表', translation: '订单列表', code: '订单列表', type: '中文(zh-CN)' },
{ id: 24621, origin: '购买商品', translation: '购买商品', code: '购买商品', type: '中文(zh-CN)' },
{ id: 24611, origin: '会员中心', translation: '会员中心', code: '会员中心', type: '中文(zh-CN)' },
{ id: 24601, origin: '就此评价', translation: '就此评价', code: '就此评价', type: '中文(zh-CN)' }
])
// ========== MOCK DATA END ==========
// ========== PAGINATION STATE ==========
const currentPage = ref(1)
const pageSize = ref(15)
const jumpPageInput = ref('')
const pageSizeOptions = [10, 15, 20, 30, 50]
const pageSizeOptionLabels = computed(() => pageSizeOptions.map((n: number) => `${n}条/页`))
const pageSizeIndex = computed(() => { const idx = pageSizeOptions.indexOf(pageSize.value); return idx >= 0 ? idx : 0 })
const total = computed(() => dataList.value.length)
const totalPage = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)))
const pagedList = computed(() => {
const start = (currentPage.value - 1) * pageSize.value
return dataList.value.slice(start, start + pageSize.value)
})
const visiblePages = computed((): number[] => {
const t = totalPage.value; const cur = currentPage.value
if (t <= 7) return Array.from({ length: t }, (_: any, i: number) => i + 1)
if (cur <= 4) return [1, 2, 3, 4, 5, -1, t]
if (cur >= t - 3) return [1, -1, t - 4, t - 3, t - 2, t - 1, t]
return [1, -1, cur - 1, cur, cur + 1, -1, t]
})
const handlePageChange = (p: number) => { currentPage.value = p }
const handlePageSizeChange = (e: any) => {
const idx = Number(e.detail.value)
pageSize.value = pageSizeOptions[idx] ?? pageSizeOptions[0]
currentPage.value = 1
}
const handleJumpPage = () => {
const p = parseInt(jumpPageInput.value)
if (!isNaN(p) && p >= 1 && p <= totalPage.value) currentPage.value = p
}
// ========== END PAGINATION STATE ==========
function onSearch() {
uni.showToast({ title: '搜索中...', icon: 'none' })
}
function addWord() {
uni.showToast({ title: '添加语句', icon: 'none' })
}
function editWord(item: any) {
uni.showToast({ title: '编辑: ' + item.origin, icon: 'none' })
}
function deleteWord(item: any) {
uni.showModal({
title: '提示',
content: '确定要删除此翻译语句吗?',
success: (res) => {
if (res.confirm) {
uni.showToast({ title: '删除成功' })
}
}
})
}
</script>
<style scoped lang="scss">
.admin-page {
/* 使用 Layout 的背景和内边距 */
min-height: 100vh;
}
.filter-row {
display: flex;
flex-direction: row;
align-items: center;
gap: 20px;
}
.filter-item {
display: flex;
flex-direction: row;
align-items: center;
}
.label {
font-size: 14px;
color: #333;
margin-right: 8px;
white-space: nowrap;
}
.filter-select {
width: 150px;
height: 32px;
border: 1px solid #d9d9d9;
border-radius: 4px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 0 10px;
}
.select-md {
width: 200px;
}
.filter-input {
width: 200px;
height: 32px;
border: 1px solid #d9d9d9;
border-radius: 4px;
padding: 0 10px;
font-size: 14px;
}
.alert-info {
background-color: #fff7e6;
border: 1px solid #ffe7ba;
padding: 20px;
border-radius: 4px;
margin: 24px 0;
}
.info-block {
display: flex;
flex-direction: column;
}
.mt-12 {
margin-top: 12px;
}
.info-title {
color: #fa8c16;
font-size: 14px;
font-weight: bold;
margin-bottom: 4px;
}
.info-content {
color: #fa8c16;
font-size: 14px;
line-height: 1.6;
}
.action-bar {
margin-bottom: 20px;
}
.admin-card {
background-color: #fff;
border-radius: 4px;
padding: 0;
overflow: hidden;
}
.btn {
height: 32px;
padding: 0 16px;
border-radius: 4px;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: none;
}
.btn.primary {
background-color: #1890ff;
color: #fff;
}
.table-container {
width: 100%;
}
.table-header {
display: flex;
flex-direction: row;
background-color: #fafafa;
border-bottom: 1px solid #f0f0f0;
}
.table-row {
display: flex;
flex-direction: row;
border-bottom: 1px solid #f0f0f0;
}
.col {
padding: 16px;
display: flex;
align-items: center;
font-size: 14px;
color: #333;
}
.col-id { width: 80px; }
.col-origin { flex: 2; }
.col-translation { flex: 2; }
.col-code { flex: 2; }
.col-type { width: 150px; }
.col-action { width: 150px; justify-content: flex-end;display: flex; flex-direction: row; }
.action-btn {
color: #1890ff;
cursor: pointer;
}
.action-btn.danger {
color: #ff4d4f;
}
.action-btn.divider {
margin: 0 8px;
color: #e8e8e8;
}
</style>