同步admin

This commit is contained in:
CQ 2025-11-13 09:44:49 +08:00
parent 16a8825962
commit ef43d9e616
21 changed files with 1148 additions and 702 deletions

143
admin/DEVELOPMENT_GUIDE.md Normal file
View File

@ -0,0 +1,143 @@
# NiuCloud Admin 开发规范
## 技术栈区分
本项目采用前后端分离架构,包含两个主要前端部分:
1. **PC端后台管理系统**
- 框架: Vue 3 + TypeScript + Vite
- UI组件库: Element Plus
- 状态管理: Pinia
- 样式处理: SCSS + Tailwind CSS
2. **移动端应用**
- 框架: uni-app + Vue 3 + TypeScript
- UI组件库: uview-plus
- 状态管理: Pinia
- 样式处理: SCSS + Windi CSS
## 关键组件使用规范
### 消息提示组件
**重要注意事项:请根据开发平台选择正确的消息提示组件!**
#### PC端 (admin目录)
- **必须使用Element Plus的消息提示组件**而不是uni-app的方法
- 主要组件包括:`ElMessage``ElMessageBox``ElNotification`
- 导入方式:`import { ElMessage, ElMessageBox } from 'element-plus'`
- 使用示例:
```typescript
import { ElMessage } from 'element-plus'
// 成功消息
ElMessage.success('操作成功')
// 错误消息
ElMessage.error('操作失败')
// 确认对话框
ElMessageBox.confirm('确定要执行此操作吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 用户点击确认后的逻辑
}).catch(() => {
// 用户点击取消后的逻辑
})
```
#### 移动端 (uni-app目录)
- **使用uni-app提供的API**进行消息提示
- 主要方法包括:`uni.showToast``uni.showModal``uni.showLoading`
- 使用示例:
```typescript
// 成功提示
uni.showToast({
title: '操作成功',
icon: 'success',
duration: 2000
})
// 模态对话框
uni.showModal({
title: '提示',
content: '确定要执行此操作吗?',
success: (res) => {
if (res.confirm) {
// 用户点击确认后的逻辑
}
}
})
```
## API请求规范
### PC端API请求
- 使用`@/utils/request.ts`封装的请求工具
- 支持`showSuccessMessage``showErrorMessage`选项控制消息显示
- 示例:
```typescript
import request from '@/utils/request'
// GET请求
export function getOrderList(params: Record<string, any>) {
return request.get('order/list', params)
}
// POST请求带成功消息
export function createOrder(params: Record<string, any>) {
return request.post('order/create', params, { showSuccessMessage: true })
}
```
### 移动端API请求
- 使用uni-app的`uni.request`或封装的请求工具
- 示例:
```typescript
// 发送请求
uni.request({
url: 'https://example.com/api/order/list',
method: 'GET',
data: {
page: 1,
limit: 10
},
success: (res) => {
// 处理成功响应
},
fail: (err) => {
// 处理请求失败
}
})
```
## 代码风格规范
1. **文件命名**
- 组件文件PascalCase`OrderList.vue`
- 普通文件kebab-case 或 camelCase`api-service.ts``commonUtils.ts`
2. **TypeScript规范**
- 为函数参数、返回值和重要变量添加明确的类型注解
- 使用接口 (interface) 定义复杂数据结构
- 避免 `any` 类型的滥用
3. **Vue组件规范**
- 使用 Vue 3 Composition API 和 `<script setup lang="ts">` 语法
- 组件样式建议使用 scoped 属性或 CSS Modules
## 国际化规范
- PC端使用Vue I18n进行国际化语言文件位于`src/lang`目录
- 移动端同样使用Vue I18n语言文件位于`src/app/locale`目录
- 使用`t('key')`函数获取翻译文本
## 其他重要规范
- 严格遵循RESTful API设计规范
- 统一处理API响应数据和错误情况
- 代码提交前确保通过TypeScript类型检查
- 组件开发遵循高内聚低耦合原则
- 优先复用现有组件和工具函数

View File

@ -9,12 +9,18 @@
"version": "1.0.0",
"dependencies": {
"@element-plus/icons-vue": "2.0.10",
"@fullcalendar/core": "^6.1.19",
"@fullcalendar/daygrid": "^6.1.19",
"@fullcalendar/interaction": "^6.1.19",
"@fullcalendar/vue3": "^6.1.19",
"@heroicons/vue": "^2.2.0",
"@highlightjs/vue-plugin": "2.1.0",
"@types/lodash-es": "4.17.6",
"@vueuse/core": "9.12.0",
"axios": "1.4.0",
"crypto-js": "4.1.1",
"css-color-function": "1.3.3",
"date-fns": "^4.1.0",
"day": "^0.0.2",
"echarts": "5.4.1",
"element-plus": "^2.7.4",
@ -963,6 +969,47 @@
"resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.1.6.tgz",
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
},
"node_modules/@fullcalendar/core": {
"version": "6.1.19",
"resolved": "https://registry.npmmirror.com/@fullcalendar/core/-/core-6.1.19.tgz",
"integrity": "sha512-z0aVlO5e4Wah6p6mouM0UEqtRf1MZZPt4mwzEyU6kusaNL+dlWQgAasF2cK23hwT4cmxkEmr4inULXgpyeExdQ==",
"dependencies": {
"preact": "~10.12.1"
}
},
"node_modules/@fullcalendar/daygrid": {
"version": "6.1.19",
"resolved": "https://registry.npmmirror.com/@fullcalendar/daygrid/-/daygrid-6.1.19.tgz",
"integrity": "sha512-IAAfnMICnVWPjpT4zi87i3FEw0xxSza0avqY/HedKEz+l5MTBYvCDPOWDATpzXoLut3aACsjktIyw9thvIcRYQ==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.19"
}
},
"node_modules/@fullcalendar/interaction": {
"version": "6.1.19",
"resolved": "https://registry.npmmirror.com/@fullcalendar/interaction/-/interaction-6.1.19.tgz",
"integrity": "sha512-GOciy79xe8JMVp+1evAU3ytdwN/7tv35t5i1vFkifiuWcQMLC/JnLg/RA2s4sYmQwoYhTw/p4GLcP0gO5B3X5w==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.19"
}
},
"node_modules/@fullcalendar/vue3": {
"version": "6.1.19",
"resolved": "https://registry.npmmirror.com/@fullcalendar/vue3/-/vue3-6.1.19.tgz",
"integrity": "sha512-j5eUSxx0xIy3ADljo0f5B9PhjqXnCQ+7nUMPfsslc2eGVjp4F74YvY3dyd6OBbg13IvpsjowkjncGipYMQWmTA==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.19",
"vue": "^3.0.11"
}
},
"node_modules/@heroicons/vue": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/@heroicons/vue/-/vue-2.2.0.tgz",
"integrity": "sha512-G3dbSxoeEKqbi/DFalhRxJU4mTXJn7GwZ7ae8NuEQzd1bqdd0jAbdaBZlHPcvPD2xI1iGzNVB4k20Un2AguYPw==",
"peerDependencies": {
"vue": ">= 3"
}
},
"node_modules/@highlightjs/vue-plugin": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/@highlightjs/vue-plugin/-/vue-plugin-2.1.0.tgz",
@ -2624,6 +2671,15 @@
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
},
"node_modules/date-fns": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-4.1.0.tgz",
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
}
},
"node_modules/day": {
"version": "0.0.2",
"resolved": "https://registry.npmmirror.com/day/-/day-0.0.2.tgz",
@ -5003,6 +5059,15 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true
},
"node_modules/preact": {
"version": "10.12.1",
"resolved": "https://registry.npmmirror.com/preact/-/preact-10.12.1.tgz",
"integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz",

View File

@ -10,12 +10,18 @@
},
"dependencies": {
"@element-plus/icons-vue": "2.0.10",
"@fullcalendar/core": "^6.1.19",
"@fullcalendar/daygrid": "^6.1.19",
"@fullcalendar/interaction": "^6.1.19",
"@fullcalendar/vue3": "^6.1.19",
"@heroicons/vue": "^2.2.0",
"@highlightjs/vue-plugin": "2.1.0",
"@types/lodash-es": "4.17.6",
"@vueuse/core": "9.12.0",
"axios": "1.4.0",
"crypto-js": "4.1.1",
"css-color-function": "1.3.3",
"date-fns": "^4.1.0",
"day": "^0.0.2",
"echarts": "5.4.1",
"element-plus": "^2.7.4",

View File

@ -18,7 +18,7 @@ export function getMemberList(params: Record<string, any>) {
* @returns
*/
export function getMemberInfo(id: number) {
return request.get(`member/member/${id}`);
return request.get(`member/member/${ id }`);
}
/**
@ -61,7 +61,7 @@ export function getRegisterChannelType(params: Record<string, any>) {
* @param member_id
*/
export function deleteMember(member_id: number) {
return request.delete(`member/member/${member_id}`, { showSuccessMessage: true })
return request.delete(`member/member/${ member_id }`, { showSuccessMessage: true })
}
/***************************************************** 会员标签 ****************************************************/
@ -81,7 +81,7 @@ export function getMemberLabelList(params: Record<string, any>) {
* @returns
*/
export function getMemberLabelInfo(label_id: number) {
return request.get(`member/label/${label_id}`);
return request.get(`member/label/${ label_id }`);
}
/**
@ -98,7 +98,7 @@ export function addMemberLabel(params: Record<string, any>) {
* @param params
*/
export function updateMemberLabel(params: Record<string, any>) {
return request.put(`member/label/${params.label_id}`, params, { showSuccessMessage: true })
return request.put(`member/label/${ params.label_id }`, params, { showSuccessMessage: true })
}
/**
@ -107,7 +107,7 @@ export function updateMemberLabel(params: Record<string, any>) {
* @returns
*/
export function deleteMemberLabel(label_id: number) {
return request.delete(`member/label/${label_id}`, { showSuccessMessage: true })
return request.delete(`member/label/${ label_id }`, { showSuccessMessage: true })
}
/**
@ -122,7 +122,7 @@ export function getMemberLabelAll() {
* @param params
*/
export function editMemberDetail(params: Record<string, any>) {
return request.put(`member/member/modify/${params.member_id}/${params.field}`, params, { showSuccessMessage: true })
return request.put(`member/member/modify/${ params.member_id }/${ params.field }`, params, { showSuccessMessage: true })
}
/**
@ -143,7 +143,7 @@ export function memberBatchModify(params: Record<string, any>) {
* @param change_type
*/
export function getChangeTypeList(change_type: string) {
return request.get(`member/account/change_type/${change_type}`)
return request.get(`member/account/change_type/${ change_type }`)
}
/**
@ -321,7 +321,7 @@ export function getBalanceStatus() {
*
*/
export function getAccountType(params: Record<string, any>) {
return request.get(`member/account/change_type/${params.account_type}`)
return request.get(`member/account/change_type/${ params.account_type }`)
}
@ -357,7 +357,7 @@ export function getCashOutList(params: Record<string, any>) {
* @param id
*/
export function getCashOutDetail(id: number) {
return request.get(`member/cash_out/${id}`, {})
return request.get(`member/cash_out/${ id }`, {})
}
/**
@ -365,14 +365,18 @@ export function getCashOutDetail(id: number) {
* @param params
*/
export function memberAudit(params: Record<string, any>) {
return request.put(`member/cash_out/audit/${params.id}/${params.action}`, params, { showSuccessMessage: true })
return request.put(`member/cash_out/audit/${ params.id }/${ params.action }`, params, { showSuccessMessage: true })
}
/**
*
* @param params
*/
export function memberCancel(params: Record<string, any>) {
return request.put(`member/cash_out/cancel/${params.id}`, params, { showSuccessMessage: true,showErrorMessage: true })
return request.put(`member/cash_out/cancel/${ params.id }`, params, {
showSuccessMessage: true,
showErrorMessage: true
})
}
@ -381,7 +385,7 @@ export function memberCancel(params: Record<string, any>) {
* @param params
*/
export function memberTransfer(params: Record<string, any>) {
return request.put(`member/cash_out/transfer/${params.id}`, params, { showSuccessMessage: true })
return request.put(`member/cash_out/transfer/${ params.id }`, params, { showSuccessMessage: true })
}
/**
@ -389,14 +393,15 @@ export function memberTransfer(params: Record<string, any>) {
* @param params
*/
export function memberRemark(params: Record<string, any>) {
return request.put(`member/cash_out/remark/${params.id}`, params, { showSuccessMessage: true })
return request.put(`member/cash_out/remark/${ params.id }`, params, { showSuccessMessage: true })
}
/**
*
* @param id
*/
export function memberCheck(id: number) {
return request.put(`member/cash_out/check/${id}`, {}, { showSuccessMessage: true })
return request.put(`member/cash_out/check/${ id }`, {}, { showSuccessMessage: true })
}
/**
@ -404,7 +409,7 @@ export function memberCheck(id: number) {
* @param params
*/
export function editMemberStatus(params: Record<string, any>) {
return request.put(`member/setstatus/${params.status}`, params, { showSuccessMessage: true })
return request.put(`member/setstatus/${ params.status }`, params, { showSuccessMessage: true })
}
/**
@ -453,6 +458,7 @@ export function getGrowthRuleDict() {
export function getPointRuleDict() {
return request.get(`member/dict/point_rule`)
}
/***************************************************** 会员等级 ****************************************************/
/**
@ -470,7 +476,7 @@ export function getMemberLevelPageList(params: Record<string, any>) {
* @returns
*/
export function getMemberLevelInfo(level_id: number) {
return request.get(`member/level/${level_id}`);
return request.get(`member/level/${ level_id }`);
}
/**
@ -487,7 +493,7 @@ export function addMemberLevel(params: Record<string, any>) {
* @param params
*/
export function updateMemberLevel(params: Record<string, any>) {
return request.put(`member/level/${params.level_id}`, params, { showSuccessMessage: true })
return request.put(`member/level/${ params.level_id }`, params, { showSuccessMessage: true })
}
/**
@ -496,7 +502,7 @@ export function updateMemberLevel(params: Record<string, any>) {
* @returns
*/
export function deleteMemberLevel(level_id: number) {
return request.delete(`member/level/${level_id}`, { showSuccessMessage: true })
return request.delete(`member/level/${ level_id }`, { showSuccessMessage: true })
}
/**
@ -512,14 +518,14 @@ export function getMemberLevelAll() {
*
*/
export function getMemberBenefitsContent() {
return request.get(`member/benefits/content`);
return request.post(`member/benefits/content`);
}
/**
*
*/
export function getMemberGiftsContent(params: Record<string, any>) {
return request.get(`member/gifts/content`, { params });
return request.post(`member/gifts/content`, params);
}
/**
@ -555,7 +561,7 @@ export function getMemberAddress(params: Record<string, any>) {
}
/**
*
*
*/
export function addMemberAddress(params: Record<string, any>) {
return request.post(`member/address`, params);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

View File

@ -29,5 +29,8 @@
"encodingAesKeyPlaceholder": "请输入EncodingAESKey",
"cleartextModeTips": "明文模式下,不使用消息体加解密功能,安全系数较低",
"compatibleModeTips": "兼容模式下,明文、密文将共存,方便开发者调试和维护",
"safeModeTips": "安全模式下,消息包为纯密文,需要开发者加密和解密,安全系数高"
}
"safeModeTips": "安全模式下,消息包为纯密文,需要开发者加密和解密,安全系数高",
"wechatBaseUri": "借权域名",
"wechatBaseUriPlaceholder": "",
"wechatBaseUriTips": "默认留空填写后将替换https://open.weixin.gg.com/获取授权!"
}

View File

@ -61,7 +61,7 @@ const getMarketingList = async () => {
// marketingList.value = res.data
loading.value = false
}
getMarketingList()
// getMarketingList()
const toLink = (item: any) => {
if (item.url) {

View File

@ -36,6 +36,11 @@
<el-input v-model.trim="formData.app_secret" :placeholder="t('appSecretPlaceholder')" class="input-width" clearable />
<div class="form-tip">{{ t('wechatAppsecretTips') }}</div>
</el-form-item>
<el-form-item :label="t('wechatBaseUri')" prop="base_uri" v-if="!formData.is_authorization">
<el-input v-model.trim="formData.base_uri" :placeholder="t('wechatBaseUriPlaceholder')" class="input-width" clearable />
<div class="form-tip">{{ t('wechatBaseUriTips') }}</div>
</el-form-item>
</el-card>
<el-card class="box-card !border-none mt-[15px]" shadow="never">
@ -140,7 +145,8 @@ const formData = reactive<Record<string, any>>({
token: '',
encoding_aes_key: '',
encryption_type: 'not_encrypt',
is_authorization: 0
is_authorization: 0,
base_uri: ''
})
const formRef = ref<FormInstance>()

View File

@ -77,6 +77,9 @@
<el-switch v-model="diyStore.global.copyright.isShow" />
<div class="text-sm text-gray-400">{{ t('此处控制当前页面版权信息是否显示') }}</div>
</el-form-item>
<el-form-item :label="t('文字颜色')" class="display-block">
<el-color-picker v-model="diyStore.global.copyright.textColor" show-alpha />
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">

View File

@ -455,7 +455,7 @@ initPage({
diyStore.components.push(com)
}
}
console.log( component.value )
loadDiyTemplatePages(data.type)
//

File diff suppressed because it is too large Load Diff

View File

@ -126,7 +126,9 @@ const prop = defineProps({
},
ignore: {
type: Array,
default: []
default: () => {
return [] // ['DIY_MAKE_PHONE_CALL']
}
}
})

View File

@ -82,6 +82,7 @@ getUrl().then((res: any) => {
// H5
const generateH5QRCode = () => {
console.log( params.value)
// URL
const queryStr = params.value
.map(item => `${encodeURIComponent(item.name)}=${encodeURIComponent(item.value)}`)

View File

@ -1,223 +1,228 @@
{
"edit": "编辑",
"delete": "删除",
"info": "详情",
"createTime": "创建时间",
"sort": "排序",
"status": "状态",
"operation": "操作",
"more": "更多",
"statusNormal": "正常",
"statusDeactivate": "停用",
"startUsing": "启用",
"confirm": "确认",
"save": "保存",
"back": "返回",
"cancel": "取消",
"search": "搜索",
"reset": "重置",
"refresh": "刷新",
"refreshSuccess": "刷新成功",
"select": "选择",
"export": "导出列表",
"exportPlaceholder": "确定要导出数据吗?",
"exportTip": "批量导出数据",
"exportConfirm": "确定并导出",
"warning": "提示",
"isShow": "是否显示",
"show": "显示",
"hidden": "隐藏",
"icon": "图标",
"userName": "用户名",
"headImg": "头像",
"accountNumber": "账号",
"accountSettings": "账号设置",
"realName": "名称",
"realNamePlaceholder": "请输入用户名称",
"password": "密码",
"confirmPassword": "确认密码",
"image": "图片",
"video": "视频",
"rename": "重命名",
"lookOver": "查看",
"selectAll": "全选",
"yes": "是",
"no": "否",
"copy": "复制",
"complete": "完成",
"copySuccess": "复制成功",
"notSupportCopy": "浏览器不支持一键复制,请手动进行复制",
"selectPlaceholder": "全部",
"provincePlaceholder": "请选择省",
"cityPlaceholder": "请选择市",
"districtPlaceholder": "请选择区/县",
"emptyData": "暂无数据",
"emptyQrCode": "暂无二维码",
"fileErr": "无法显示",
"upload": {
"root": "上传",
"selectimage": "选择图片",
"selectvideo": "选择视频",
"selecticon": "选择图标",
"selectnews": "选择图文",
"uploadimage": "上传图片",
"uploadvideo": "上传视频",
"addAttachmentCategory": "添加分组",
"attachmentCategoryPlaceholder": "请输入分组名称",
"attachmentEmpty": "暂无附件,请点击上传按钮上传",
"iconEmpty": "暂无图标",
"deleteCategoryTips": "确定要删除该分组吗?",
"deleteAttachmentTips": "确定要删除所选附件吗?如所选附件已被使用删除将会受到影响,请谨慎操作!",
"move": "移动",
"moveCategory": "移动分组",
"moveTo": "移动至",
"placeholderimageName": "请输入图片名称",
"placeholdervideoName": "请输入视频名称",
"placeholdericonName": "请输入图标名称",
"success": "上传成功",
"triggerUpperLimit": "可选数量已达上限",
"mediaEmpty": "暂无素材,请点击上传按钮上传"
},
"tabs": {
"closeLeft": "关闭左侧",
"closeRight": "关闭右侧",
"closeOther": "关闭其他"
},
"layout": {
"layoutSetting": "主题设置",
"darkMode": "黑暗模式",
"sidebarMode": "主题风格",
"themeColor": "主题颜色",
"detectionLoginOperation": "确定",
"detectionLoginContent": "已检测到有其他账号登录,需要刷新后才能继续操作。",
"detectionLoginTip": "提示",
"layoutStyle": "布局风格",
"tab": "开启标签栏"
},
"axios": {
"unknownError": "未知错误",
"400": "错误的请求",
"401": "请重新登录",
"403": "拒绝访问",
"404": "请求错误",
"405": "请求方法未允许",
"408": "请求超时",
"409": "请求跨域",
"500": "服务器内部错误",
"501": "网络未实现",
"502": "网络错误",
"503": "服务不可用",
"504": "网络超时",
"505": "http版本不支持该请求",
"timeout": "网络请求超时!",
"requestError": "请求错误",
"errNetwork": "网络请求错误",
"baseUrlError": " 接口请求错误,请检查VITE_APP_BASE_URL参数配置或者伪静态配置, <a style='text-decoration: underline;' href='https://www.kancloud.cn/niucloud/niucloud-admin-develop/3213750' target='blank'>点击查看相关手册</a>"
},
"linkPlaceholder": "请选择跳转链接",
"selectLinkTips": "链接选择",
"diyLinkName": "链接名称",
"diyLinkNamePlaceholder": "请输入链接名称",
"diyLinkNameNotEmpty": "链接名称不能为空",
"diyLinkUrl": "跳转路径",
"diyLinkUrlPlaceholder": "请输入跳转路径",
"diyLinkUrlNotEmpty": "跳转路径不能为空",
"diyAppletId": "小程序AppID",
"diyAppletIdPlaceholder": "请输入要打开的小程序的appid",
"diyAppletIdNotEmpty": "小程序AppID不能为空",
"diyAppletPage": "小程序路径",
"diyAppletPagePlaceholder": "请输入要打开的小程序路径",
"diyAppletPageNotEmpty": "小程序路径不能为空",
"diyMakePhone": "电话号码",
"diyMakePhonePlaceholder": "请输入电话号码",
"diyMakePhoneNotEmpty": "电话号码不能为空",
"returnToPreviousPage": "返回",
"preview": "预览",
"emptyApp": "暂未安装任何应用",
"newInfo": "最新消息",
"visitWap": "访问店铺",
"mapSetting": "地图设置",
"mapKey": "腾讯地图KEY",
"indexTemplate": "首页模版",
"indexSwitch": "切换首页",
"indexWarning": "你确定要切换首页吗?",
"originalPassword": "原始密码",
"newPassword": "新密码",
"passwordCopy": "确认密码",
"passwordTip": "修改密码时必填.不修改密码时留空",
"originalPasswordPlaceholder": "请输入原始密码",
"passwordPlaceholder": "请输入新密码",
"originalPasswordHint": "原始密码不能为空",
"newPasswordHint": "请输入确认密码",
"doubleCipherHint": "两次新密码不同",
"confirmPasswordError": "两次新密码不同",
"upgrade": {
"upgradeButton": "立即升级",
"title": "升级",
"upgradingTips": "有正在执行的升级任务,",
"clickView": "点击查看",
"dirPermission": "目录读写权限",
"path": "路径",
"demand": "要求",
"readable": "可读",
"write": "可写",
"upgradeSuccess": "升级成功",
"localBuild": "本地编译",
"cloudBuild": "重试",
"rollback": "回滚",
"showDialogCloseTips": "升级任务尚未完成,关闭将取消升级,是否要继续关闭?",
"upgradeCompleteTips": "升级完成后还必须要重新编译admin wap web端以免影响到程序正常运行。",
"upgradeTips": "应用和插件升级时,系统会自动备份当前程序及数据库。升级功能不会造成您当前程序的损坏或者数据的丢失,请放心使用,但是升级过程可能会因为兼容性等各种原因出现意外的升级错误,当出现错误时,系统将会自动回退上一版本!若回退失败,请参考链接<a href='https://www.kancloud.cn/niushop/niushop_v6/3228611' target='_blank' class='text-primary'> https://www.kancloud.cn/niushop/niushop_v6/3228611 </a>手动回退上一版本!",
"knownToKnow": "我已知晓,不需要再次提示",
"cloudBuildErrorTips": "一键云编译队列任务过多,请等待几分钟后重试!",
"isNeedBackup": "是否需要备份",
"isNeedBackupTips": "检测到已存在备份,此次升级是否需要备份,不需要备份在升级出现异常时将会恢复最近的一次备份。",
"isNeedBackupBtn": "查看备份记录",
"option": "选项",
"isNeedCloudbuild": "是否需要云编译",
"cloudbuildTips": "此次升级的同时是否需要进行云编译"
},
"cloudbuild": {
"title": "云编译",
"executingTips": "有正在执行的编译任务,",
"clickView": "点击查看",
"dirPermission": "目录读写权限",
"path": "路径",
"demand": "要求",
"readable": "可读",
"write": "可写",
"cloudbuildSuccess": "编译完成",
"showDialogCloseTips": "编译任务尚未完成,关闭将取消编译,是否要继续关闭?"
},
"formSelectContentTitle": "表单名称",
"formSelectContentTitlePlaceholder": "请输入表单名称",
"formSelectContentTypeName": "表单类型",
"formSelectContentTypeNamePlaceholder": "请选择表单类型",
"formSelectContentTypeAll": "全部",
"formSelectContentTips": "请选择表单",
"appName": "应用名/版本信息",
"appIdentification": "应用标识",
"introduction": "简介",
"type": "类型",
"localAppText": "插件管理",
"upgrade2": "升级",
"installLabel": "已安装",
"uninstalledLabel": "未安装",
"buyLabel": "已购买",
"cloudBuild": "云编译",
"newVersion": "最新版本",
"tipText": "标识指开发应用或插件的文件夹名称",
"gxx": "更新信息",
"return": "返回",
"nextStep": "下一步",
"prev": "上一步",
"viewUpgradeContent": "查看升级内容",
"testDirectoryPermissions": "检测目录权限",
"backupFiles": "备份文件",
"startUpgrade": "开始升级",
"upgradeEnd": "升级完成",
"cloudBuildTips": "是否要进行云编译该操作可能会影响到正在访问的客户是否要继续操作?",
"promoteUrl": "推广链接",
"downLoadQRCode": "下载二维码",
"configureFailed": "配置失败"
}
"edit": "编辑",
"delete": "删除",
"info": "详情",
"createTime": "创建时间",
"sort": "排序",
"status": "状态",
"operation": "操作",
"more": "更多",
"statusNormal": "正常",
"statusDeactivate": "停用",
"startUsing": "启用",
"confirm": "确认",
"save": "保存",
"back": "返回",
"cancel": "取消",
"search": "搜索",
"reset": "重置",
"refresh": "刷新",
"refreshSuccess": "刷新成功",
"select": "选择",
"export": "导出列表",
"exportPlaceholder": "确定要导出数据吗?",
"exportTip": "批量导出数据",
"exportConfirm": "确定并导出",
"warning": "提示",
"isShow": "是否显示",
"show": "显示",
"hidden": "隐藏",
"icon": "图标",
"userName": "用户名",
"headImg": "头像",
"accountNumber": "账号",
"accountSettings": "账号设置",
"realName": "名称",
"realNamePlaceholder": "请输入用户名称",
"password": "密码",
"confirmPassword": "确认密码",
"image": "图片",
"video": "视频",
"rename": "重命名",
"lookOver": "查看",
"selectAll": "全选",
"yes": "是",
"no": "否",
"copy": "复制",
"complete": "完成",
"copySuccess": "复制成功",
"notSupportCopy": "浏览器不支持一键复制,请手动进行复制",
"selectPlaceholder": "全部",
"provincePlaceholder": "请选择省",
"cityPlaceholder": "请选择市",
"districtPlaceholder": "请选择区/县",
"emptyData": "暂无数据",
"emptyQrCode": "暂无二维码",
"fileErr": "无法显示",
"upload": {
"root": "上传",
"selectimage": "选择图片",
"selectvideo": "选择视频",
"selecticon": "选择图标",
"selectnews": "选择图文",
"uploadimage": "上传图片",
"uploadvideo": "上传视频",
"addAttachmentCategory": "添加分组",
"attachmentCategoryPlaceholder": "请输入分组名称",
"attachmentEmpty": "暂无附件,请点击上传按钮上传",
"iconEmpty": "暂无图标",
"deleteCategoryTips": "确定要删除该分组吗?",
"deleteAttachmentTips": "确定要删除所选附件吗?如所选附件已被使用删除将会受到影响,请谨慎操作!",
"move": "移动",
"moveCategory": "移动分组",
"moveTo": "移动至",
"placeholderimageName": "请输入图片名称",
"placeholdervideoName": "请输入视频名称",
"placeholdericonName": "请输入图标名称",
"success": "上传成功",
"triggerUpperLimit": "可选数量已达上限",
"mediaEmpty": "暂无素材,请点击上传按钮上传"
},
"tabs": {
"closeLeft": "关闭左侧",
"closeRight": "关闭右侧",
"closeOther": "关闭其他"
},
"layout": {
"layoutSetting": "主题设置",
"darkMode": "黑暗模式",
"sidebarMode": "主题风格",
"themeColor": "主题颜色",
"detectionLoginOperation": "确定",
"detectionLoginContent": "已检测到有其他账号登录,需要刷新后才能继续操作。",
"detectionLoginTip": "提示",
"layoutStyle": "布局风格",
"tab": "开启标签栏"
},
"axios": {
"unknownError": "未知错误",
"400": "错误的请求",
"401": "请重新登录",
"403": "拒绝访问",
"404": "请求错误",
"405": "请求方法未允许",
"408": "请求超时",
"409": "请求跨域",
"500": "服务器内部错误",
"501": "网络未实现",
"502": "网络错误",
"503": "服务不可用",
"504": "网络超时",
"505": "http版本不支持该请求",
"timeout": "网络请求超时!",
"requestError": "请求错误",
"errNetwork": "网络请求错误",
"baseUrlError": " 接口请求错误,请检查VITE_APP_BASE_URL参数配置或者伪静态配置, <a style='text-decoration: underline;' href='https://www.kancloud.cn/niucloud/niucloud-admin-develop/3213750' target='blank'>点击查看相关手册</a>"
},
"linkPlaceholder": "请选择跳转链接",
"selectLinkTips": "链接选择",
"diyLinkName": "链接名称",
"diyLinkNamePlaceholder": "请输入链接名称",
"diyLinkNameNotEmpty": "链接名称不能为空",
"diyLinkUrl": "跳转路径",
"diyLinkUrlPlaceholder": "请输入跳转路径",
"diyLinkUrlNotEmpty": "跳转路径不能为空",
"diyAppletId": "小程序AppID",
"diyAppletIdPlaceholder": "请输入要打开的小程序的appid",
"diyAppletIdNotEmpty": "小程序AppID不能为空",
"diyAppletPage": "小程序路径",
"diyAppletPagePlaceholder": "请输入要打开的小程序路径",
"diyAppletPageNotEmpty": "小程序路径不能为空",
"diyMakePhone": "电话号码",
"diyMakePhonePlaceholder": "请输入电话号码",
"diyMakePhoneNotEmpty": "电话号码不能为空",
"returnToPreviousPage": "返回",
"preview": "预览",
"emptyApp": "暂未安装任何应用",
"newInfo": "最新消息",
"visitWap": "访问店铺",
"mapSetting": "地图设置",
"mapKey": "腾讯地图KEY",
"indexTemplate": "首页模版",
"indexSwitch": "切换首页",
"indexWarning": "你确定要切换首页吗?",
"originalPassword": "原始密码",
"newPassword": "新密码",
"passwordCopy": "确认密码",
"passwordTip": "修改密码时必填.不修改密码时留空",
"originalPasswordPlaceholder": "请输入原始密码",
"passwordPlaceholder": "请输入新密码",
"originalPasswordHint": "原始密码不能为空",
"newPasswordHint": "请输入确认密码",
"doubleCipherHint": "两次新密码不同",
"confirmPasswordError": "两次新密码不同",
"upgrade": {
"upgradeButton": "立即升级",
"title": "升级",
"upgradingTips": "有正在执行的升级任务,",
"clickView": "点击查看",
"dirPermission": "目录读写权限",
"path": "路径",
"demand": "要求",
"readable": "可读",
"write": "可写",
"upgradeSuccess": "升级成功",
"localBuild": "本地编译",
"cloudBuild": "重试",
"rollback": "回滚",
"showDialogCloseTips": "升级任务尚未完成,关闭将取消升级,是否要继续关闭?",
"upgradeCompleteTips": "升级完成后还必须要重新编译admin wap web端以免影响到程序正常运行。",
"upgradeTips": "应用和插件升级时,系统会自动备份当前程序及数据库。升级功能不会造成您当前程序的损坏或者数据的丢失,请放心使用,但是升级过程可能会因为兼容性等各种原因出现意外的升级错误,当出现错误时,系统将会自动回退上一版本!若回退失败,请参考链接<a href='https://www.kancloud.cn/niushop/niushop_v6/3228611' target='_blank' class='text-primary'> https://www.kancloud.cn/niushop/niushop_v6/3228611 </a>手动回退上一版本!",
"knownToKnow": "我已知晓,不需要再次提示",
"cloudBuildErrorTips": "一键云编译队列任务过多,请等待几分钟后重试!",
"isNeedBackup": "是否需要备份",
"isNeedBackupTips": "检测到已存在备份,此次升级是否需要备份,不需要备份在升级出现异常时将会恢复最近的一次备份。",
"isNeedBackupBtn": "查看备份记录",
"option": "选项",
"isNeedCloudbuild": "是否需要云编译",
"cloudbuildTips": "此次升级的同时是否需要进行云编译"
},
"cloudbuild": {
"title": "云编译",
"executingTips": "有正在执行的编译任务,",
"clickView": "点击查看",
"dirPermission": "目录读写权限",
"path": "路径",
"demand": "要求",
"readable": "可读",
"write": "可写",
"cloudbuildSuccess": "编译完成",
"showDialogCloseTips": "编译任务尚未完成,关闭将取消编译,是否要继续关闭?"
},
"formSelectContentTitle": "表单名称",
"formSelectContentTitlePlaceholder": "请输入表单名称",
"formSelectContentTypeName": "表单类型",
"formSelectContentTypeNamePlaceholder": "请选择表单类型",
"formSelectContentTypeAll": "全部",
"formSelectContentTips": "请选择表单",
"appName": "应用名/版本信息",
"appIdentification": "应用标识",
"introduction": "简介",
"type": "类型",
"localAppText": "插件管理",
"upgrade2": "升级",
"installLabel": "已安装",
"uninstalledLabel": "未安装",
"buyLabel": "已购买",
"cloudBuild": "云编译",
"newVersion": "最新版本",
"tipText": "标识指开发应用或插件的文件夹名称",
"gxx": "更新信息",
"return": "返回",
"nextStep": "下一步",
"prev": "上一步",
"viewUpgradeContent": "查看升级内容",
"testDirectoryPermissions": "检测目录权限",
"backupFiles": "备份文件",
"startUpgrade": "开始升级",
"upgradeEnd": "升级完成",
"cloudBuildTips": "是否要进行云编译该操作可能会影响到正在访问的客户是否要继续操作?",
"promoteUrl": "推广链接",
"downLoadQRCode": "下载二维码",
"configureFailed": "配置失败",
"lefttitle": "左侧标题",
"righttitle": "右侧标题",
"leftDesc": "左侧简介",
"rightDesc": "右侧简介",
"descPlaceholder": "请输入简介内容"
}

View File

@ -17,10 +17,10 @@
<div v-if="systemStore.menuIsCollapse" class="text-left text-[14px] mt-[3px] w-[75px] using-hidden ml-[10px]">{{ item.meta.title || item.meta.short_title }}</div>
<div v-else class="text-center text-[12px] using-hidden mt-1">{{ item.meta.short_title || item.meta.title }}</div>
<div v-if="systemStore.menuIsCollapse && item.name=='app_store' && recentlyUpdated.length>0" class="text-[11px] bg-[#DA203E] px-[10px] rounded-[12px] text-[#fff] absolute right-[6px]">更新</div>
<div v-if="!systemStore.menuIsCollapse && item.name=='app_store' && recentlyUpdated.length>0" class="w-[7px] h-[7px] bg-[#DA203E] absolute flex items-center justify-center rounded-full top-[4px] right-[14px]"></div>
<div v-if="systemStore.menuIsCollapse && item.original_name=='tool' && isNewVersion" class="text-[11px] bg-[#DA203E] px-[10px] rounded-[12px] text-[#fff] absolute right-[6px]">更新</div>
<div v-if="!systemStore.menuIsCollapse && item.original_name=='tool' && isNewVersion" class="w-[7px] h-[7px] bg-[#DA203E] absolute flex items-center justify-center rounded-full top-[4px] right-[14px]"></div>
<div v-if="systemStore.menuIsCollapse && item.name=='app_store' && (recentlyUpdated.length>0 || isNewVersion)" class="text-[11px] bg-[#DA203E] px-[10px] rounded-[12px] text-[#fff] absolute right-[6px]">更新</div>
<div v-if="!systemStore.menuIsCollapse && item.name=='app_store' && (recentlyUpdated.length>0 || isNewVersion)" class="w-[7px] h-[7px] bg-[#DA203E] absolute flex items-center justify-center rounded-full top-[4px] right-[14px]"></div>
<!-- <div v-if="systemStore.menuIsCollapse && item.original_name=='tool' && isNewVersion" class="text-[11px] bg-[#DA203E] px-[10px] rounded-[12px] text-[#fff] absolute right-[6px]">更新</div>
<div v-if="!systemStore.menuIsCollapse && item.original_name=='tool' && isNewVersion" class="w-[7px] h-[7px] bg-[#DA203E] absolute flex items-center justify-center rounded-full top-[4px] right-[14px]"></div> -->
</div>
</template>

View File

@ -87,6 +87,7 @@ const useDiyStore = defineStore('diy', {
copyright: {
control: true, // 是否允许展示编辑
isShow: false, // 是否显示
textColor : "#ccc", // 文字颜色
},
// 弹框 count不弹出 -1首次弹出 1每次弹出 0
popWindow: {
@ -190,6 +191,7 @@ const useDiyStore = defineStore('diy', {
copyright: {
control: true, // 是否允许展示编辑
isShow: true, // 是否显示
textColor : "#ccc", // 文字颜色
},
// 弹框 count不弹出 -1首次弹出 1每次弹出 0

View File

@ -1,9 +1,9 @@
@font-face {
font-family: "iconfont";
/* Project id 3883393 */
src: url('//at.alicdn.com/t/c/font_3883393_6d60cyygl4.woff2?t=1755603992297') format('woff2'),
url('//at.alicdn.com/t/c/font_3883393_6d60cyygl4.woff?t=1755603992297') format('woff'),
url('//at.alicdn.com/t/c/font_3883393_6d60cyygl4.ttf?t=1755603992297') format('truetype');
src: url('//at.alicdn.com/t/c/font_3883393_0604cbkh5j03.woff2?t=1762651161569') format('woff2'),
url('//at.alicdn.com/t/c/font_3883393_0604cbkh5j03.woff?t=1762651161569') format('woff'),
url('//at.alicdn.com/t/c/font_3883393_0604cbkh5j03.ttf?t=1762651161569') format('truetype');
}
.iconfont {
@ -14,6 +14,78 @@
-moz-osx-font-smoothing: grayscale;
}
.icona-zhulixiangqingpc30:before {
content: "\e914";
}
.icona-zuidijiapc30:before {
content: "\e915";
}
.icona-zhulipc30:before {
content: "\e916";
}
.icona-zhulijiapc30:before {
content: "\e917";
}
.icona-kanhoujiapc30:before {
content: "\e918";
}
.icona-jiagepc30:before {
content: "\e919";
}
.icona-zhuliwanfapc30:before {
content: "\e91a";
}
.icona-zhulipc301:before {
content: "\e91b";
}
.icona-zhulilunbopc30:before {
content: "\e91c";
}
.icona-canyuxinxipc30:before {
content: "\e91d";
}
.icona-zhulixiangqingpc301:before {
content: "\e91e";
}
.iconyoujiantou:before {
content: "\e913";
}
.iconanzhuang1:before {
content: "\e90d";
}
.icongengxin:before {
content: "\e90e";
}
.iconliebiao:before {
content: "\e90f";
}
.iconyijianshengji:before {
content: "\e910";
}
.iconliebiaoqiehuan:before {
content: "\e911";
}
.iconyijianxiufu:before {
content: "\e912";
}
.icona-bijiPC30:before {
content: "\e90b";
}

View File

@ -131,8 +131,9 @@ export function img(path: string): string {
if (typeof path == 'string' && path.startsWith('/')) path = path.replace(/^\//, '')
if (typeof imgDomain == 'string' && imgDomain.endsWith('/')) imgDomain = imgDomain.slice(0, -1)
return isUrl(path) ? path : `${imgDomain}/${path}`
if(path){
return isUrl(path) ? path : `${imgDomain}/${path}`
}
}
/**