Browse Source

首次提交

master
liutong 2 years ago
parent
commit
04faa3bc82
  1. 20
      LICENSE
  2. 13
      admin/.env.development
  3. 13
      admin/.env.production
  4. 27
      admin/.eslintrc.json
  5. 24
      admin/.gitignore
  6. 18
      admin/README.md
  7. 5
      admin/auto-imports.d.ts
  8. 96
      admin/components.d.ts
  9. 13
      admin/index.html
  10. 6949
      admin/package-lock.json
  11. 58
      admin/package.json
  12. 6
      admin/postcss.config.cjs
  13. BIN
      admin/public/niucloud.ico
  14. 39
      admin/publish.cjs
  15. 38
      admin/src/App.vue
  16. 52
      admin/src/addon/hygl/api/advertising.ts
  17. 29
      admin/src/addon/hygl/api/common.ts
  18. 60
      admin/src/addon/hygl/api/config.ts
  19. 52
      admin/src/addon/hygl/api/coupons.ts
  20. 7
      admin/src/addon/hygl/api/hello_world.ts
  21. 52
      admin/src/addon/hygl/api/transaction_history.ts
  22. 61
      admin/src/addon/hygl/api/user.ts
  23. 54
      admin/src/addon/hygl/api/user_coupons.ts
  24. 17
      admin/src/addon/hygl/lang/zh-cn/advertising.advertising.json
  25. 33
      admin/src/addon/hygl/lang/zh-cn/config.config.json
  26. 26
      admin/src/addon/hygl/lang/zh-cn/coupons.coupons.json
  27. 1
      admin/src/addon/hygl/lang/zh-cn/hello_world.index.json
  28. 33
      admin/src/addon/hygl/lang/zh-cn/transaction_history.transaction_history.json
  29. 34
      admin/src/addon/hygl/lang/zh-cn/user.user.json
  30. 21
      admin/src/addon/hygl/lang/zh-cn/user_coupons.user_coupons.json
  31. 171
      admin/src/addon/hygl/views/advertising/advertising.vue
  32. 174
      admin/src/addon/hygl/views/advertising/components/advertising-edit.vue
  33. 257
      admin/src/addon/hygl/views/config/components/config-edit.vue
  34. 378
      admin/src/addon/hygl/views/config/config.vue
  35. 238
      admin/src/addon/hygl/views/coupons/components/coupons-edit.vue
  36. 227
      admin/src/addon/hygl/views/coupons/coupons.vue
  37. 17
      admin/src/addon/hygl/views/hello_world/index.vue
  38. 295
      admin/src/addon/hygl/views/transaction_history/components/transaction-history-edit.vue
  39. 286
      admin/src/addon/hygl/views/transaction_history/transaction_history.vue
  40. 311
      admin/src/addon/hygl/views/user/components/user-edit.vue
  41. 283
      admin/src/addon/hygl/views/user/user.vue
  42. 233
      admin/src/addon/hygl/views/user_coupons/components/user-coupons-edit.vue
  43. 249
      admin/src/addon/hygl/views/user_coupons/user_coupons.vue
  44. 92
      admin/src/app/api/addon.ts
  45. 26
      admin/src/app/api/aliapp.ts
  46. 48
      admin/src/app/api/auth.ts
  47. 38
      admin/src/app/api/cloud.ts
  48. 81
      admin/src/app/api/dict.ts
  49. 183
      admin/src/app/api/diy.ts
  50. 18
      admin/src/app/api/h5.ts
  51. 5
      admin/src/app/api/home.ts
  52. 354
      admin/src/app/api/member.ts
  53. 67
      admin/src/app/api/module.ts
  54. 81
      admin/src/app/api/notice.ts
  55. 70
      admin/src/app/api/order.ts
  56. 71
      admin/src/app/api/pay.ts
  57. 18
      admin/src/app/api/personal.ts
  58. 252
      admin/src/app/api/site.ts
  59. 17
      admin/src/app/api/stat.ts
  60. 702
      admin/src/app/api/sys.ts
  61. 184
      admin/src/app/api/tools.ts
  62. 47
      admin/src/app/api/upgrade.ts
  63. 58
      admin/src/app/api/user.ts
  64. 125
      admin/src/app/api/weapp.ts
  65. 64
      admin/src/app/api/wechat.ts
  66. BIN
      admin/src/app/assets/images/SaaS.png
  67. BIN
      admin/src/app/assets/images/app_default.png
  68. BIN
      admin/src/app/assets/images/app_store/app_store_default.png
  69. BIN
      admin/src/app/assets/images/app_store/local_icon.png
  70. BIN
      admin/src/app/assets/images/app_store/local_icon_select.png
  71. BIN
      admin/src/app/assets/images/app_store/market_icon.png
  72. BIN
      admin/src/app/assets/images/app_store/market_icon_select.png
  73. BIN
      admin/src/app/assets/images/app_store/switch_icon_1.png
  74. BIN
      admin/src/app/assets/images/app_store/switch_icon_2.png
  75. BIN
      admin/src/app/assets/images/back_login.jpg
  76. BIN
      admin/src/app/assets/images/category_default.png
  77. BIN
      admin/src/app/assets/images/channel/preview.png
  78. BIN
      admin/src/app/assets/images/default_headimg.png
  79. BIN
      admin/src/app/assets/images/diy/notice/style_01.png
  80. BIN
      admin/src/app/assets/images/diy/text/style1.png
  81. BIN
      admin/src/app/assets/images/diy/text/style2.png
  82. BIN
      admin/src/app/assets/images/diy_preview_head.png
  83. BIN
      admin/src/app/assets/images/empty.png
  84. BIN
      admin/src/app/assets/images/error.png
  85. BIN
      admin/src/app/assets/images/gov_icon.png
  86. BIN
      admin/src/app/assets/images/icon-addon.png
  87. BIN
      admin/src/app/assets/images/icon_folder.png
  88. BIN
      admin/src/app/assets/images/icon_preview.png
  89. BIN
      admin/src/app/assets/images/index/add_menu.png
  90. BIN
      admin/src/app/assets/images/index/administrator.png
  91. BIN
      admin/src/app/assets/images/index/app.png
  92. BIN
      admin/src/app/assets/images/index/app1.png
  93. BIN
      admin/src/app/assets/images/index/app_default.png
  94. BIN
      admin/src/app/assets/images/index/apply_empty.png
  95. BIN
      admin/src/app/assets/images/index/article.png
  96. BIN
      admin/src/app/assets/images/index/article_list.png
  97. BIN
      admin/src/app/assets/images/index/auth.png
  98. BIN
      admin/src/app/assets/images/index/auth1.png
  99. BIN
      admin/src/app/assets/images/index/balance.png
  100. BIN
      admin/src/app/assets/images/index/del_model.png

20
LICENSE

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2023 niucloud-admin
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

13
admin/.env.development

@ -0,0 +1,13 @@
NODE_ENV = 'development'
# 本地开发-api请求地址
VITE_APP_BASE_URL='http://zfgl.cc/index.php/adminapi/'
# 图片服务器地址
VITE_IMG_DOMAIN='http://zfgl.cc'
# 请求时header中token的参数名
VITE_REQUEST_HEADER_TOKEN_KEY='token'
# 请求时header中站点的参数名
VITE_REQUEST_HEADER_SITEID_KEY='site-id'

13
admin/.env.production

@ -0,0 +1,13 @@
NODE_ENV = 'production'
# api请求地址
VITE_APP_BASE_URL='/adminapi/'
# 图片服务器地址
VITE_IMG_DOMAIN=''
# 请求时header中token的参数名
VITE_REQUEST_HEADER_TOKEN_KEY='token'
# 请求时header中站点的参数名
VITE_REQUEST_HEADER_SITEID_KEY='site-id'

27
admin/.eslintrc.json

@ -0,0 +1,27 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"plugin:vue/vue3-essential",
"standard-with-typescript",
"eslint:recommended"
],
"overrides": [
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"parser": "@typescript-eslint/parser"
},
"plugins": [
"vue",
"@typescript-eslint"
],
"rules": {
"no-tabs":"off",
"indent": [1, 4, { "SwitchCase": 1 }],
"eqeqeq":"off"
}
}

24
admin/.gitignore

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

18
admin/README.md

@ -0,0 +1,18 @@
# Vue 3 + TypeScript + Vite
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
## Type Support For `.vue` Imports in TS
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
1. Disable the built-in TypeScript Extension
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.

5
admin/auto-imports.d.ts

@ -0,0 +1,5 @@
// Generated by 'unplugin-auto-import'
export {}
declare global {
const ElNotification: typeof import('element-plus/es')['ElNotification']
}

96
admin/components.d.ts

@ -0,0 +1,96 @@
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'
export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
Attachment: typeof import('./src/components/upload-attachment/attachment.vue')['default']
DiyLink: typeof import('./src/components/diy-link/index.vue')['default']
Editor: typeof import('./src/components/editor/index.vue')['default']
ElAlert: typeof import('element-plus/es')['ElAlert']
ElAside: typeof import('element-plus/es')['ElAside']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
ElCol: typeof import('element-plus/es')['ElCol']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage']
ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElLink: typeof import('element-plus/es')['ElLink']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
ElOptionGroup: typeof import('element-plus/es')['ElOptionGroup']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElResult: typeof import('element-plus/es')['ElResult']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSlider: typeof import('element-plus/es')['ElSlider']
ElStatistic: typeof import('element-plus/es')['ElStatistic']
ElStep: typeof import('element-plus/es')['ElStep']
ElSteps: typeof import('element-plus/es')['ElSteps']
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElTimeline: typeof import('element-plus/es')['ElTimeline']
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
ElUpload: typeof import('element-plus/es')['ElUpload']
HeatMap: typeof import('./src/components/heat-map/index.vue')['default']
Icon: typeof import('./src/components/icon/index.vue')['default']
PopoverInput: typeof import('./src/components/popover-input/index.vue')['default']
RangeInput: typeof import('./src/components/range-input/index.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SelectArea: typeof import('./src/components/select-area/index.vue')['default']
SelectIcon: typeof import('./src/components/select-icon/index.vue')['default']
UploadAttachment: typeof import('./src/components/upload-attachment/index.vue')['default']
UploadFile: typeof import('./src/components/upload-file/index.vue')['default']
UploadImage: typeof import('./src/components/upload-image/index.vue')['default']
UploadVideo: typeof import('./src/components/upload-video/index.vue')['default']
Verify: typeof import('./src/components/verifition/Verify.vue')['default']
VerifyPoints: typeof import('./src/components/verifition/Verify/VerifyPoints.vue')['default']
VerifySlide: typeof import('./src/components/verifition/Verify/VerifySlide.vue')['default']
VideoPlayer: typeof import('./src/components/video-player/index.vue')['default']
}
export interface ComponentCustomProperties {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}

13
admin/index.html

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image" href="/niucloud.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

6949
admin/package-lock.json

File diff suppressed because it is too large

58
admin/package.json

@ -0,0 +1,58 @@
{
"name": "admin",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build && node publish.cjs",
"preview": "vite preview"
},
"dependencies": {
"@element-plus/icons-vue": "2.0.10",
"@highlightjs/vue-plugin": "2.1.0",
"@vueuse/core": "9.12.0",
"@wangeditor/editor": "5.1.23",
"@wangeditor/editor-for-vue": "5.1.12",
"@types/lodash-es": "4.17.6",
"axios": "1.4.0",
"crypto-js": "4.1.1",
"css-color-function": "1.3.3",
"echarts": "5.4.1",
"element-plus": "2.2.29",
"nprogress": "0.2.0",
"pinia": "2.0.30",
"qrcode": "1.5.1",
"sass": "1.58.0",
"sortablejs": "1.15.0",
"vue": "3.2.45",
"vue-i18n": "9.2.2",
"vue-router": "4.1.6",
"vue-web-terminal": "3.2.2",
"vue3-video-play": "1.3.1-beta.6",
"vue-jsonp": "2.0.0",
"lodash-es": "4.17.21",
"highlight.js": "11.0.1"
},
"devDependencies": {
"@tailwindcss/line-clamp": "0.4.2",
"@types/qrcode": "1.5.0",
"@types/sortablejs": "1.15.0",
"@typescript-eslint/eslint-plugin": "5.53.0",
"@vitejs/plugin-vue": "4.0.0",
"autoprefixer": "10.4.13",
"eslint": "8.34.0",
"eslint-config-standard-with-typescript": "34.0.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-n": "15.6.1",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-vue": "9.9.0",
"postcss": "8.4.21",
"tailwindcss": "3.2.4",
"typescript": "4.9.5",
"unplugin-auto-import": "0.13.0",
"unplugin-vue-components": "0.23.0",
"vite": "4.1.0",
"vue-tsc": "1.0.24"
}
}

6
admin/postcss.config.cjs

@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
}

BIN
admin/public/niucloud.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

39
admin/publish.cjs

@ -0,0 +1,39 @@
const fs = require('fs')
const publish = () => {
const src = './dist'
const dest = '../niucloud/public/admin'
solve()
// 目标目录不存在停止复制
try {
const dir = fs.readdirSync(dest)
} catch (e) {
return
}
// 删除目标目录下文件
fs.rm(dest, { recursive: true }, err => {
if(err) {
console.log(err)
return
}
fs.cp(src, dest, { recursive: true }, (err) => {
if (err) {
console.error(err)
}
})
})
}
const solve = () => {
const fn = './dist/index.html'
const fc = fs.readFileSync(fn, 'utf-8')
let text = new String(fc)
text = text.replaceAll('./assets/', '/admin/assets/')
fs.writeFileSync(fn, text, 'utf8')
}
publish()

38
admin/src/App.vue

@ -0,0 +1,38 @@
<template>
<el-config-provider :locale="locale">
<router-view></router-view>
</el-config-provider>
</template>
<script lang="ts" setup>
import { computed, onMounted, watch } from 'vue'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import en from 'element-plus/dist/locale/en.mjs'
import useSystemStore from '@/stores/modules/system'
import useAppStore from '@/stores/modules/app'
import { useDark, useToggle } from '@vueuse/core'
import { setThemeColor } from '@/utils/common'
import { useRoute } from 'vue-router'
const route = useRoute()
// 初始化设置语言
const systemStore = useSystemStore()
const locale = computed(() => (systemStore.lang === 'zh-cn' ? zhCn : en))
const toggleDark = useToggle(useDark())
watch(route, () => {
useAppStore().$patch(state => {
state.route = route
})
}, { immediate: true })
onMounted(() => {
// 设置主题色
toggleDark(systemStore.dark)
setThemeColor(systemStore.theme, systemStore.dark ? 'dark' : 'light')
})
</script>
<style lang="scss" scoped></style>

52
admin/src/addon/hygl/api/advertising.ts

@ -0,0 +1,52 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- hygl_advertising
/**
* 获取广告管理列表
* @param params
* @returns
*/
export function getAdvertisingList(params: Record<string, any>) {
return request.get(`hygl/advertising`, {params})
}
/**
* 获取广告管理详情
* @param id 广告管理id
* @returns
*/
export function getAdvertisingInfo(id: number) {
return request.get(`hygl/advertising/${id}`);
}
/**
* 添加广告管理
* @param params
* @returns
*/
export function addAdvertising(params: Record<string, any>) {
return request.post('hygl/advertising', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 编辑广告管理
* @param id
* @param params
* @returns
*/
export function editAdvertising(params: Record<string, any>) {
return request.put(`hygl/advertising/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 删除广告管理
* @param id
* @returns
*/
export function deleteAdvertising(id: number) {
return request.delete(`hygl/advertising/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
// USER_CODE_END -- hygl_advertising

29
admin/src/addon/hygl/api/common.ts

@ -0,0 +1,29 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- hygl_common
/**
* 上传文件到本地
* @param params
* @returns
*/
export function uploadFile(params: FormData) {
let config = {
headers: {
"Content-Type": "multipart/form-data",
}
}
return request.post('hygl/uploadFile', params,config)
}
/**
* 获取远程搜索优惠券下拉菜单
* @param params
*/
export function getWithCouponsList(params: Record<string,any>){
return request.get('hygl/getCouponsList', {params})
}
// USER_CODE_END -- hygl_common

60
admin/src/addon/hygl/api/config.ts

@ -0,0 +1,60 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- hygl_config
/**
* 获取配置项列表
* @param params
* @returns
*/
export function getConfigList(params: Record<string, any>) {
return request.get(`hygl/config`, {params})
}
/**
* 获取配置项详情
* @param id 配置项id
* @returns
*/
export function getConfigInfo(id: number) {
return request.get(`hygl/config/${id}`);
}
/**
* 添加配置项
* @param params
* @returns
*/
export function addConfig(params: Record<string, any>) {
return request.post('hygl/config', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 编辑配置项
* @param id
* @param params
* @returns
*/
export function editConfig(params: Record<string, any>) {
return request.put(`hygl/config/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 删除配置项
* @param id
* @returns
*/
export function deleteConfig(id: number) {
return request.delete(`hygl/config/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 重新生成H5站点二维码
* @param id
*/
export function resetH5SiteQRCode(id: number) {
return request.get(`hygl/config/resetH5SiteQRCode/${id}`);
}
// USER_CODE_END -- hygl_config

52
admin/src/addon/hygl/api/coupons.ts

@ -0,0 +1,52 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- hygl_coupons
/**
* 获取优惠券列表
* @param params
* @returns
*/
export function getCouponsList(params: Record<string, any>) {
return request.get(`hygl/coupons`, {params})
}
/**
* 获取优惠券详情
* @param id 优惠券id
* @returns
*/
export function getCouponsInfo(id: number) {
return request.get(`hygl/coupons/${id}`);
}
/**
* 添加优惠券
* @param params
* @returns
*/
export function addCoupons(params: Record<string, any>) {
return request.post('hygl/coupons', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 编辑优惠券
* @param id
* @param params
* @returns
*/
export function editCoupons(params: Record<string, any>) {
return request.put(`hygl/coupons/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 删除优惠券
* @param id
* @returns
*/
export function deleteCoupons(id: number) {
return request.delete(`hygl/coupons/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
// USER_CODE_END -- hygl_coupons

7
admin/src/addon/hygl/api/hello_world.ts

@ -0,0 +1,7 @@
import request from '@/utils/request'
/***************************************************** hello world ****************************************************/
export function getHelloWorld() {
return request.get(`hygl/hello_world`)
}

52
admin/src/addon/hygl/api/transaction_history.ts

@ -0,0 +1,52 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- hygl_transaction_history
/**
* 获取会员交易记录列表
* @param params
* @returns
*/
export function getTransactionHistoryList(params: Record<string, any>) {
return request.get(`hygl/transaction_history`, {params})
}
/**
* 获取会员交易记录详情
* @param id 会员交易记录id
* @returns
*/
export function getTransactionHistoryInfo(id: number) {
return request.get(`hygl/transaction_history/${id}`);
}
/**
* 添加会员交易记录
* @param params
* @returns
*/
export function addTransactionHistory(params: Record<string, any>) {
return request.post('hygl/transaction_history', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 编辑会员交易记录
* @param id
* @param params
* @returns
*/
export function editTransactionHistory(params: Record<string, any>) {
return request.put(`hygl/transaction_history/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 删除会员交易记录
* @param id
* @returns
*/
export function deleteTransactionHistory(id: number) {
return request.delete(`hygl/transaction_history/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
// USER_CODE_END -- hygl_transaction_history

61
admin/src/addon/hygl/api/user.ts

@ -0,0 +1,61 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- hygl_user
/**
* 获取会员管理列表
* @param params
* @returns
*/
export function getUserList(params: Record<string, any>) {
return request.get(`hygl/user`, {params})
}
/**
* 获取会员管理详情
* @param id 会员管理id
* @returns
*/
export function getUserInfo(id: number) {
return request.get(`hygl/user/${id}`);
}
/**
* 添加会员管理
* @param params
* @returns
*/
export function addUser(params: Record<string, any>) {
return request.post('hygl/user', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 编辑会员管理
* @param id
* @param params
* @returns
*/
export function editUser(params: Record<string, any>) {
return request.put(`hygl/user/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 删除会员管理
* @param id
* @returns
*/
export function deleteUser(id: number) {
return request.delete(`hygl/user/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
//获取全部站点
export function getWithSiteList(params: Record<string, any>) {
return request.get('hygl/site', {params})
}
//获取全部用户
export function getWithUserList(params: Record<string, any>) {
return request.get('hygl/user', {params})
}
// USER_CODE_END -- hygl_user

54
admin/src/addon/hygl/api/user_coupons.ts

@ -0,0 +1,54 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- hygl_user_coupons
/**
* 获取用户优惠券列表
* @param params
* @returns
*/
export function getUserCouponsList(params: Record<string, any>) {
return request.get(`hygl/user_coupons`, {params})
}
/**
* 获取用户优惠券详情
* @param id 用户优惠券id
* @returns
*/
export function getUserCouponsInfo(id: number) {
return request.get(`hygl/user_coupons/${id}`);
}
/**
* 添加用户优惠券
* @param params
* @returns
*/
export function addUserCoupons(params: Record<string, any>) {
return request.post('hygl/user_coupons', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 编辑用户优惠券
* @param id
* @param params
* @returns
*/
export function editUserCoupons(params: Record<string, any>) {
return request.put(`hygl/user_coupons/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 删除用户优惠券
* @param id
* @returns
*/
export function deleteUserCoupons(id: number) {
return request.delete(`hygl/user_coupons/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithUserList(params: Record<string,any>){
return request.get('hygl/user', {params})
}
// USER_CODE_END -- hygl_user_coupons

17
admin/src/addon/hygl/lang/zh-cn/advertising.advertising.json

@ -0,0 +1,17 @@
{
"id":"序号",
"siteId":"站点",
"siteIdPlaceholder":"请输入站点",
"imgUrl":"广告图",
"imgUrlPlaceholder":"请输入广告图",
"skipUrl":"跳转链接",
"skipUrlPlaceholder":"请输入跳转链接",
"sort":"排序",
"sortPlaceholder":"请输入排序",
"createTime":"创建时间",
"addAdvertising":"添加广告管理",
"updateAdvertising":"编辑广告管理",
"advertisingDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

33
admin/src/addon/hygl/lang/zh-cn/config.config.json

@ -0,0 +1,33 @@
{
"id":"id",
"siteId":"站点id",
"siteIdPlaceholder":"请输入站点id",
"weChatPayAppid":"微信支付-APP的id",
"weChatPayAppidPlaceholder":"请输入微信支付-APP的id",
"weChatPayAppId":"微信支付-公众号APPID",
"weChatPayAppIdPlaceholder":"请输入微信支付-公众号APPID",
"weChatPayMiniappId":"微信支付-小程序APPID",
"weChatPayMiniappIdPlaceholder":"请输入微信支付-小程序APPID",
"weChatPayMchId":"微信支付-商户号",
"weChatPayMchIdPlaceholder":"请输入微信支付-商户号",
"weChatPayKey":"微信支付-商户号秘钥",
"weChatPayKeyPlaceholder":"请输入微信支付-商户号秘钥",
"weChatPayMiniappSecret":"微信支付-小程序secret",
"weChatPayMiniappSecretPlaceholder":"请输入微信支付-小程序secret",
"weChatPayNotifyUrl":"微信支付-异步回调地址",
"weChatPayNotifyUrlPlaceholder":"请输入微信支付-异步回调地址",
"alipayAppId":"支付宝-appid",
"alipayAppIdPlaceholder":"请输入支付宝-appid",
"alipayRsaPrivateKey":"支付宝-开发者私钥",
"alipayRsaPrivateKeyPlaceholder":"请输入支付宝-开发者私钥",
"alipayPublicKey":"支付宝-支付宝公钥",
"alipayPublicKeyPlaceholder":"请输入支付宝-支付宝公钥",
"alipayNotifyUrl":"支付宝-异步回调地址",
"alipayNotifyUrlPlaceholder":"请输入支付宝-异步回调地址",
"createTime":"创建时间",
"addConfig":"添加配置项",
"updateConfig":"编辑配置项",
"configDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

26
admin/src/addon/hygl/lang/zh-cn/coupons.coupons.json

@ -0,0 +1,26 @@
{
"id": "id",
"siteId": "站点id",
"siteIdPlaceholder": "请输入站点id",
"name": "卡券名字",
"namePlaceholder": "请输入卡券名字",
"nominalValue": "卡券面值",
"nominalValuePlaceholder": "请输入卡券面值",
"stock": "卡券库存",
"stockPlaceholder": "请输入卡券库存",
"isShow": "是否展示",
"isShowPlaceholder": "请输入是否展示",
"isLongTermValid": "是否长期有效",
"isLongTermValidPlaceholder": "请输入是否长期有效",
"createTime": "创建时间",
"addCoupons": "添加优惠券",
"updateCoupons": "编辑优惠券",
"couponsDeleteTips": "确定要删除该数据吗?",
"startDate": "请选择开始时间",
"endDate": "请选择结束时间",
"validFrom": "有效期开始时间",
"validUntil": "有效期截止时间",
"validTime": "有效期",
"isObsolete": "是否作废",
"isObsoletePlaceholder": "请输入是否作废"
}

1
admin/src/addon/hygl/lang/zh-cn/hello_world.index.json

@ -0,0 +1 @@
{}

33
admin/src/addon/hygl/lang/zh-cn/transaction_history.transaction_history.json

@ -0,0 +1,33 @@
{
"id":"序号",
"siteId":"站点id",
"siteIdPlaceholder":"请输入站点id",
"userId":"用户",
"userIdPlaceholder":"请输入用户",
"remark":"用户备注",
"remarkPlaceholder":"请输入用户备注",
"orderNum":"我方订单号",
"orderNumPlaceholder":"请输入我方订单号",
"payNum":"支付平台订单号",
"payNumPlaceholder":"请输入支付平台订单号",
"payType":"支付方式",
"payTypePlaceholder":"请输入支付方式",
"price":"订单应付金额(元)",
"pricePlaceholder":"请输入订单应付金额(元)",
"cashFee":"用户实际支付金额(元)",
"cashFeePlaceholder":"请输入用户实际支付金额(元)",
"payStatus":"是否完成支付",
"payStatusPlaceholder":"请输入是否完成支付",
"payTime":"用户付款时间",
"payTimePlaceholder":"请输入用户付款时间",
"payDataJson":"支付回调json字符串|默认null,支付成功后异步回调的值",
"payDataJsonPlaceholder":"请输入支付回调json字符串|默认null,支付成功后异步回调的值",
"createTime":"创建时间",
"createTimePlaceholder":"请输入创建时间",
"addTransactionHistory":"添加会员交易记录",
"updateTransactionHistory":"编辑会员交易记录",
"transactionHistoryDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间",
"couponsInfo":"优惠券使用"
}

34
admin/src/addon/hygl/lang/zh-cn/user.user.json

@ -0,0 +1,34 @@
{
"id":"id",
"idPlaceholder":"请输入",
"siteId":"站点id",
"siteIdPlaceholder":"请输入站点id",
"tel":"联系电话",
"telPlaceholder":"请输入联系电话",
"name":"姓名",
"namePlaceholder":"请输入姓名",
"pic":"用户头像|相对路径",
"picPlaceholder":"请输入用户头像",
"password":"密码",
"passwordPlaceholder":"请输入密码",
"pid":"用户上级",
"pidPlaceholder":"请输入用户上级",
"level":"会员层级",
"levelPlaceholder":"请输入会员层级",
"wxOpenid":"微信小程序openid",
"wxOpenidPlaceholder":"请输入微信小程序openid",
"wxUnionid":"微信unionid",
"wxUnionidPlaceholder":"请输入微信unionid",
"sex":"性别",
"sexPlaceholder":"请输入性别",
"birthday":"生日",
"birthdayPlaceholder":"请输入生日",
"isShow":"是否可用",
"isShowPlaceholder":"请输入是否可用",
"createTime":"创建时间",
"addUser":"添加会员管理",
"updateUser":"编辑会员管理",
"userDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

21
admin/src/addon/hygl/lang/zh-cn/user_coupons.user_coupons.json

@ -0,0 +1,21 @@
{
"id":"id",
"userId":"用户id",
"userIdPlaceholder":"全部",
"siteId":"站点id",
"siteIdPlaceholder":"请输入站点id",
"couponsId":"卡券名字",
"couponsIdPlaceholder":"请输入卡券名字",
"nominalValue":"卡券面值",
"nominalValuePlaceholder":"请输入卡券面值",
"isShow":"是否可用",
"isShowPlaceholder":"请输入是否可用",
"createTime":"创建时间",
"createTimePlaceholder":"请输入创建时间",
"addUserCoupons":"添加用户优惠券",
"updateUserCoupons":"编辑用户优惠券",
"userCouponsDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间",
"validTime":"有效期"
}

171
admin/src/addon/hygl/views/advertising/advertising.vue

@ -0,0 +1,171 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-lg">{{ pageName }}</span>
<el-button type="primary" @click="addEvent">
{{ t('addAdvertising') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="advertisingTable.searchParam" ref="searchFormRef">
<el-form-item>
<el-button type="primary" @click="loadAdvertisingList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<div class="mt-[10px]">
<el-table :data="advertisingTable.data" size="large" v-loading="advertisingTable.loading">
<template #empty>
<span>{{ !advertisingTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('imgUrl')" width="100" align="left">
<template #default="{ row }">
<el-avatar v-if="row.img_url" :src="img(row.img_url)"/>
<el-avatar v-else icon="UserFilled"/>
</template>
</el-table-column>
<el-table-column prop="skip_url" :label="t('skipUrl')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="sort" :label="t('sort')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('createTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.create_time || '' }}
</template>
</el-table-column>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="advertisingTable.page" v-model:page-size="advertisingTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="advertisingTable.total"
@size-change="loadAdvertisingList()" @current-change="loadAdvertisingList"/>
</div>
</div>
<edit ref="editAdvertisingDialog" @complete="loadAdvertisingList"/>
</el-card>
</div>
</template>
<script lang="ts" setup>
import {reactive, ref, watch} from 'vue'
import {t} from '@/lang'
import {useDictionary} from '@/app/api/dict'
import {getAdvertisingList, deleteAdvertising,} from '@/addon/hygl/api/advertising'
import {img} from '@/utils/common'
import {ElMessageBox, FormInstance} from 'element-plus'
import Edit from '@/addon/hygl/views/advertising/components/advertising-edit.vue'
import {useRoute} from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let advertisingTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {}
})
const searchFormRef = ref<FormInstance>()
// 选中数据
const selectData = ref<any[]>([])
// 字典数据
/**
* 获取广告管理列表
*/
const loadAdvertisingList = (page: number = 1) => {
advertisingTable.loading = true
advertisingTable.page = page
getAdvertisingList({
page: advertisingTable.page,
limit: advertisingTable.limit,
...advertisingTable.searchParam
}).then(res => {
advertisingTable.loading = false
advertisingTable.data = res.data.data
advertisingTable.total = res.data.total
}).catch(() => {
advertisingTable.loading = false
})
}
loadAdvertisingList()
const editAdvertisingDialog: Record<string, any> | null = ref(null)
/**
* 添加广告管理
*/
const addEvent = () => {
editAdvertisingDialog.value.setFormData()
editAdvertisingDialog.value.showDialog = true
}
/**
* 编辑广告管理
* @param data
*/
const editEvent = (data: any) => {
editAdvertisingDialog.value.setFormData(data)
editAdvertisingDialog.value.showDialog = true
}
/**
* 删除广告管理
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('advertisingDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteAdvertising(id).then(() => {
loadAdvertisingList()
}).catch(() => {
})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadAdvertisingList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

174
admin/src/addon/hygl/views/advertising/components/advertising-edit.vue

@ -0,0 +1,174 @@
<template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateAdvertising') : t('addAdvertising')" width="50%"
class="diy-dialog-wrap"
:destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form"
v-loading="loading">
<el-form-item :label="t('imgUrl')">
<upload-image v-model="formData.img_url"/>
</el-form-item>
<el-form-item :label="t('skipUrl')">
<el-input v-model="formData.skip_url" clearable :placeholder="t('skipUrlPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('sort')" prop="sort">
<el-input-number v-model="formData.sort" clearable :placeholder="t('sortPlaceholder')" class="input-width"/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import {ref, reactive, computed, watch} from 'vue'
import {useDictionary} from '@/app/api/dict'
import {t} from '@/lang'
import type {FormInstance} from 'element-plus'
import {addAdvertising, editAdvertising, getAdvertisingInfo,} from '@/addon/hygl/api/advertising'
let showDialog = ref(false)
const loading = ref(false)
/**
* 表单数据
*/
const initialFormData = {
id: '',
img_url: '',
skip_url: '',
sort: '1',
}
const formData: Record<string, any> = reactive({...initialFormData})
const formRef = ref<FormInstance>()
// 表单验证规则
const formRules = computed(() => {
return {
img_url: [
{required: true, message: t('imgUrlPlaceholder'), trigger: 'blur'},
]
,
skip_url: [
{required: true, message: t('skipUrlPlaceholder'), trigger: 'blur'},
]
,
sort: [
{required: true, message: t('sortPlaceholder'), trigger: 'blur'},
{
validator: (rule: any, value: string, callback: any) => {
if (value && !/^\d{1,9999}$/.test(value)) {
callback(new Error(t('generateBetween')))
} else {
callback()
}
}
},
]
,
}
})
const emit = defineEmits(['complete'])
/**
* 确认
* @param formEl
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
let save = formData.id ? editAdvertising : addAdvertising
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
let data = formData
save(data).then(res => {
loading.value = false
showDialog.value = false
emit('complete')
}).catch(err => {
loading.value = false
})
}
})
}
// 获取字典数据
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if (row) {
const data = await (await getAdvertisingInfo(row.id)).data
if (data) Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
// 验证手机号格式
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
// 验证身份证号
const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
// 验证邮箱号
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
// 验证请输入整数
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

257
admin/src/addon/hygl/views/config/components/config-edit.vue

@ -0,0 +1,257 @@
<template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateConfig') : t('addConfig')" width="50%"
class="diy-dialog-wrap"
:destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form"
v-loading="loading">
<el-form-item :label="t('weChatPayAppid')">
<el-input v-model="formData.we_chat_pay_appid" clearable :placeholder="t('weChatPayAppidPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('weChatPayAppId')">
<el-input v-model="formData.we_chat_pay_app_id" clearable :placeholder="t('weChatPayAppIdPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('weChatPayMiniappId')">
<el-input v-model="formData.we_chat_pay_miniapp_id" clearable :placeholder="t('weChatPayMiniappIdPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('weChatPayMchId')">
<el-input v-model="formData.we_chat_pay_mch_id" clearable :placeholder="t('weChatPayMchIdPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('weChatPayKey')">
<el-input v-model="formData.we_chat_pay_key" clearable :placeholder="t('weChatPayKeyPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('weChatPayMiniappSecret')">
<el-input v-model="formData.we_chat_pay_miniapp_secret" clearable
:placeholder="t('weChatPayMiniappSecretPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('weChatPayNotifyUrl')" prop="we_chat_pay_notify_url">
<el-input v-model="formData.we_chat_pay_notify_url" clearable :placeholder="t('weChatPayNotifyUrlPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('alipayAppId')">
<el-input v-model="formData.alipay_appId" clearable :placeholder="t('alipayAppIdPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('alipayRsaPrivateKey')">
<el-input v-model="formData.alipay_rsa_private_key" clearable :placeholder="t('alipayRsaPrivateKeyPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('alipayPublicKey')">
<el-input v-model="formData.alipay_public_key" clearable :placeholder="t('alipayPublicKeyPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('alipayNotifyUrl')" prop="alipay_notify_url">
<el-input v-model="formData.alipay_notify_url" clearable :placeholder="t('alipayNotifyUrlPlaceholder')"
class="input-width"/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import {ref, reactive, computed, watch} from 'vue'
import {useDictionary} from '@/app/api/dict'
import {t} from '@/lang'
import type {FormInstance} from 'element-plus'
import {addConfig, editConfig, getConfigInfo,} from '@/addon/hygl/api/config'
let showDialog = ref(false)
const loading = ref(false)
/**
* 表单数据
*/
const initialFormData = {
id: '',
we_chat_pay_appid: '',
we_chat_pay_app_id: '',
we_chat_pay_miniapp_id: '',
we_chat_pay_mch_id: '',
we_chat_pay_key: '',
we_chat_pay_miniapp_secret: '',
we_chat_pay_notify_url: '',
alipay_appId: '',
alipay_rsa_private_key: '',
alipay_public_key: '',
alipay_notify_url: '',
}
const formData: Record<string, any> = reactive({...initialFormData})
const formRef = ref<FormInstance>()
// 表单验证规则
const formRules = computed(() => {
return {
we_chat_pay_appid: [
{required: true, message: t('weChatPayAppidPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_app_id: [
{required: true, message: t('weChatPayAppIdPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_miniapp_id: [
{required: true, message: t('weChatPayMiniappIdPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_mch_id: [
{required: true, message: t('weChatPayMchIdPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_key: [
{required: true, message: t('weChatPayKeyPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_miniapp_secret: [
{required: true, message: t('weChatPayMiniappSecretPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_notify_url: [
{required: true, message: t('weChatPayNotifyUrlPlaceholder'), trigger: 'blur'},
]
,
alipay_appId: [
{required: true, message: t('alipayAppIdPlaceholder'), trigger: 'blur'},
]
,
alipay_rsa_private_key: [
{required: true, message: t('alipayRsaPrivateKeyPlaceholder'), trigger: 'blur'},
]
,
alipay_public_key: [
{required: true, message: t('alipayPublicKeyPlaceholder'), trigger: 'blur'},
]
,
alipay_notify_url: [
{required: true, message: t('alipayNotifyUrlPlaceholder'), trigger: 'blur'},
]
,
}
})
const emit = defineEmits(['complete'])
/**
* 确认
* @param formEl
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
let save = formData.id ? editConfig : addConfig
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
let data = formData
save(data).then(res => {
loading.value = false
showDialog.value = false
emit('complete')
}).catch(err => {
loading.value = false
})
}
})
}
// 获取字典数据
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if (row) {
const data = await (await getConfigInfo(row.id)).data
if (data) Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
// 验证手机号格式
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
// 验证身份证号
const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
// 验证邮箱号
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
// 验证请输入整数
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

378
admin/src/addon/hygl/views/config/config.vue

@ -0,0 +1,378 @@
<template>
<div class="main-container">
<div class="detail-head">
<!-- <div class="left" @click="back()">-->
<!-- <span class="iconfont iconxiangzuojiantou !text-xs"></span>-->
<!-- <span class="ml-[1px]">{{ t('returnToPreviousPage') }}</span>-->
<!-- </div>-->
<!-- <span class="adorn">|</span>-->
<span class="right">{{ pageName }}</span>
</div>
<el-card class="box-card !border-none" shadow="never">
<el-form :model="formData" label-width="270px" ref="formRef" :rules="formRules" class="page-form">
<!--
<el-form-item :label="t('weChatPayAppid')">
<el-input v-model="formData.we_chat_pay_appid" clearable :placeholder="t('weChatPayAppidPlaceholder')"
class="input-width"/>
</el-form-item>
-->
<el-form-item :label="t('weChatPayAppId')" prop="we_chat_pay_app_id">
<el-input v-model="formData.we_chat_pay_app_id" clearable :placeholder="t('weChatPayAppIdPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('weChatPayMiniappId')">
<el-input v-model="formData.we_chat_pay_miniapp_id" clearable
:placeholder="t('weChatPayMiniappIdPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('weChatPayMchId')" prop="we_chat_pay_mch_id">
<el-input v-model="formData.we_chat_pay_mch_id" clearable :placeholder="t('weChatPayMchIdPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('weChatPayKey')" prop="we_chat_pay_key">
<el-input v-model="formData.we_chat_pay_key" clearable :placeholder="t('weChatPayKeyPlaceholder')"
class="input-width"/>
</el-form-item>
<!--
<el-form-item :label="t('weChatPayMiniappSecret')">
<el-input v-model="formData.we_chat_pay_miniapp_secret" clearable
:placeholder="t('weChatPayMiniappSecretPlaceholder')" class="input-width"/>
</el-form-item>
-->
<el-form-item :label="t('weChatPayNotifyUrl')" prop="we_chat_pay_notify_url">
<el-input disabled="true" v-model="formData.we_chat_pay_notify_url" clearable
:placeholder="t('weChatPayNotifyUrlPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('上传微信商户私钥(apiclient_key.pem)')" prop="we_chat_pay_mch_secret_cert">
<el-input v-model="formData.we_chat_pay_mch_secret_cert" clearable
:placeholder="t('请上传商户私钥')" class="input-width"/>
<div>
<input type="file"
@change="handleFileUpload($event,'we_chat_pay_mch_secret_cert','config_we_chat_pay_mch_secret_cert')">
</div>
</el-form-item>
<el-form-item :label="t('上传微信商户公钥(apiclient_cert.pem)')" prop="we_chat_pay_mch_public_cert_path">
<el-input v-model="formData.we_chat_pay_mch_public_cert_path" clearable
:placeholder="t('请上传商户公钥')" class="input-width"/>
<input type="file"
@change="handleFileUpload($event,'we_chat_pay_mch_public_cert_path','config_we_chat_pay_mch_public_cert_path')">
</el-form-item>
<!--
<el-form-item :label="t('alipayAppId')">
<el-input v-model="formData.alipay_appId" clearable :placeholder="t('alipayAppIdPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('alipayRsaPrivateKey')">
<el-input v-model="formData.alipay_rsa_private_key" clearable
:placeholder="t('alipayRsaPrivateKeyPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('alipayPublicKey')">
<el-input v-model="formData.alipay_public_key" clearable :placeholder="t('alipayPublicKeyPlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('alipayNotifyUrl')" prop="alipay_notify_url">
<el-input v-model="formData.alipay_notify_url" clearable :placeholder="t('alipayNotifyUrlPlaceholder')"
class="input-width"/>
</el-form-item>
-->
<el-form-item :label="t('H5站点地址')" prop="h5_site_url">
<el-input disabled="true" v-model="formData.h5_site_url" clearable
:placeholder="t('H5站点地址')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('H5站点二维码')" prop="h5_qrcode_url">
<el-input disabled="true" v-model="formData.h5_qrcode_url" clearable :placeholder="t('H5站点二维码')"
class="input-width"/>
<el-button style="margin-left: 15px;" type="primary" @click="resetQrCode()">{{ t('重新生成二维码') }}</el-button>
</el-form-item>
<el-form-item v-if="formData.ol_h5_qrcode_url" :label="t('原始H5站点二维码')" prop="h5_qrcode_url">
<div>
<p style="color: red;">重新生成二维码后->点击"保存"将替换此二维码</p>
<img :src="formData.ol_h5_qrcode_url" alt="">
<a :href="formData.ol_h5_qrcode_url" target="downloadFile" download="h5_qrcode.png">
<el-button type="primary">打开二维码</el-button>
</a>
</div>
</el-form-item>
<el-form-item :label="t('微信小程序跳转路径')" prop="miniapp_site_url">
<el-input disabled="true" v-model="formData.miniapp_site_url" clearable
:placeholder="t('微信小程序跳转路径')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('微信小程序二维码')" prop="miniapp_qrcode_url">
<el-input disabled="true" v-model="formData.miniapp_qrcode_url" clearable :placeholder="t('微信小程序二维码')"
class="input-width"/>
<el-button style="margin-left: 15px;" type="primary" @click="resetMiniAppQrCode()">{{ t('重新生成二维码') }}</el-button>
</el-form-item>
<el-form-item v-if="formData.ol_miniapp_qrcode_url" :label="t('原始微信小程序二维码')" prop="miniapp_qrcode_url">
<div>
<p style="color: red;">重新生成二维码后->点击"保存"将替换此二维码</p>
<img :src="formData.ol_miniapp_qrcode_url" alt="">
<a :href="formData.ol_miniapp_qrcode_url" target="downloadFile" download="miniapp_qrcode.png">
<el-button type="primary">打开二维码</el-button>
</a>
</div>
</el-form-item>
</el-form>
</el-card>
<div class="fixed-footer-wrap">
<div class="fixed-footer">
<el-button type="primary" @click="onSave(formRef)">{{ t('save') }}</el-button>
<!-- <el-button @click="back()">{{ t('cancel') }}</el-button>-->
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import {ref, reactive, computed, watch} from 'vue'
import {t} from '@/lang'
import {useDictionary} from '@/app/api/dict'
import type {FormInstance} from 'element-plus'
import {getConfigInfo, addConfig, editConfig, getConfigList, resetH5SiteQRCode,} from '@/addon/hygl/api/config';
import {useRoute} from 'vue-router'
import {ElMessage} from 'element-plus'
import {uploadFile} from "@/addon/hygl/api/common";
const route = useRoute()
const id: number = parseInt(route.query.id);
const loading = ref(false)
const pageName = route.meta.title
/**
* 表单数据
*/
const initialFormData = {
id: 0,
we_chat_pay_appid: '',
we_chat_pay_app_id: '',
we_chat_pay_miniapp_id: '',
we_chat_pay_mch_id: '',
we_chat_pay_key: '',
we_chat_pay_miniapp_secret: '',
we_chat_pay_notify_url: '',
alipay_appId: '',
alipay_rsa_private_key: '',
alipay_public_key: '',
alipay_notify_url: '',
we_chat_pay_mch_secret_cert: '',
we_chat_pay_mch_public_cert_path: '',
h5_site_url:'',
h5_qrcode_url:'',
ol_h5_qrcode_url:'',
}
const formData: Record<string, any> = reactive({...initialFormData})
const setFormData = async (id: number = 0) => {
Object.assign(formData, initialFormData)
const data = await (await getConfigInfo(id)).data
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
setFormData();
const formRef = ref<FormInstance>()
// 选中数据
const selectData = ref<any[]>([])
// 字典数据
// 表单验证规则
const formRules = computed(() => {
return {
we_chat_pay_appid: [
{required: true, message: t('weChatPayAppidPlaceholder'), trigger: 'blur'},
],
we_chat_pay_app_id: [
{required: true, message: t('weChatPayAppIdPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_miniapp_id: [
{required: true, message: t('weChatPayMiniappIdPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_mch_id: [
{required: true, message: t('weChatPayMchIdPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_key: [
{required: true, message: t('weChatPayKeyPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_miniapp_secret: [
{required: true, message: t('weChatPayMiniappSecretPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_notify_url: [
{required: true, message: t('weChatPayNotifyUrlPlaceholder'), trigger: 'blur'},
]
,
we_chat_pay_mch_secret_cert: [
{required: true, message: t('商户私钥必传'), trigger: 'blur'},
],
we_chat_pay_mch_public_cert_path: [
{required: true, message: t('商户公钥必传'), trigger: 'blur'},
],
alipay_appId: [
{required: true, message: t('alipayAppIdPlaceholder'), trigger: 'blur'},
],
alipay_rsa_private_key: [
{required: true, message: t('alipayRsaPrivateKeyPlaceholder'), trigger: 'blur'},
]
,
alipay_public_key: [
{required: true, message: t('alipayPublicKeyPlaceholder'), trigger: 'blur'},
]
,
alipay_notify_url: [
{required: true, message: t('alipayNotifyUrlPlaceholder'), trigger: 'blur'},
]
,
}
})
const onSave = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
let data = formData
const save = editConfig
save(data).then(res => {
loading.value = false
setFormData()//刷新页面
// history.back()
}).catch(err => {
loading.value = false
})
}
})
}
// 验证手机号格式
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
// 验证身份证号
const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
// 验证邮箱号
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
// 验证请输入整数
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
const back = () => {
history.back()
}
//重新生成二维码
const resetQrCode = async () => {
let data = formData
if (!data.id) {
ElMessage({
message: '请先填写必要信息并点击保存后再试',
type: 'warning',
})
return
}
let aa = resetH5SiteQRCode(data.id).then(res => {
if (res.code){
formData.h5_qrcode_url = res.data.url
}
// history.back()
}).catch(err => {
console.log(err)
})
}
//上传文件(单文件上传)
const handleFileUpload = (event: Event, name: string, path: string) => {
const fileInput = event.target as HTMLInputElement;
if (!fileInput.files || fileInput.files.length === 0) {
return;
}
const file = fileInput.files[0];
let form_data = new FormData();
form_data.append('file', file); // 使用正确的 file 变量
form_data.append('path', path); // 使用正确的 path 变量
uploadFile(form_data).then(res => {
console.log(222, res)
if (res.code) {
formData[name] = res.data.file_path
}
// loading.value = false
// history.back()
}).catch(err => {
// loading.value = false
})
};
</script>
<style lang="scss" scoped></style>

238
admin/src/addon/hygl/views/coupons/components/coupons-edit.vue

@ -0,0 +1,238 @@
<template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateCoupons') : t('addCoupons')" width="50%"
class="diy-dialog-wrap"
:destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form"
v-loading="loading">
<el-form-item :label="t('name')" prop="name">
<el-input v-model="formData.name" clearable :placeholder="t('namePlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('nominalValue')" prop="nominal_value">
<el-input-number v-model="formData.nominal_value" clearable :placeholder="t('nominalValuePlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('stock')" prop="stock">
<el-input-number v-model="formData.stock" clearable :placeholder="t('stockPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('isShow')" prop="is_show">
<el-radio-group v-model="formData.is_show" :placeholder="t('isShowPlaceholder')">
<el-radio
v-for="(item, index) in is_showList"
:key="index"
:label="item.value">
{{ item.name }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('isObsolete')" prop="is_obsolete">
<el-radio-group v-model="formData.is_obsolete" :placeholder="t('isObsoletePlaceholder')">
<el-radio label="1">是</el-radio>
<el-radio label="0">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('isLongTermValid')" prop="is_long_term_valid">
<el-radio-group v-model="formData.is_long_term_valid" :placeholder="t('isLongTermValidPlaceholder')">
<el-radio label="1">是</el-radio>
<el-radio label="0">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-show="formData.is_long_term_valid !=='1'" :label="t('validTime')" prop="valid_time">
<el-date-picker v-model="formData.valid_time" type="daterange"
value-format="YYYY-MM-DD"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')"/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import {ref, reactive, computed, watch} from 'vue'
import {useDictionary} from '@/app/api/dict'
import {t} from '@/lang'
import type {FormInstance} from 'element-plus'
import {addCoupons, editCoupons, getCouponsInfo,} from '@/addon/hygl/api/coupons'
let showDialog = ref(false)
const loading = ref(false)
/**
* 表单数据
*/
const initialFormData = {
id: '',
name: '',
nominal_value: '',
stock: '100',
is_show: '1',
is_long_term_valid: '1',
is_obsolete: '0',
valid_time: [],
}
const formData: Record<string, any> = reactive({...initialFormData})
const formRef = ref<FormInstance>()
// 表单验证规则
const formRules = computed(() => {
return {
name: [
{required: true, message: t('namePlaceholder'), trigger: 'blur'},
]
,
nominal_value: [
{ required: true, message: t('nominalValuePlaceholder'), trigger: 'blur' },
{
validator: (rule: any, value: string, callback: any) => {
const floatValue = parseFloat(value);
if (isNaN(floatValue) || floatValue <= 0 || floatValue > 99999 || !/^\d+(\.\d{1,2})?$/.test(value)) {
callback(new Error(t('请输入0.1-99999')))
} else {
callback()
}
}
},
]
,
stock: [
{required: true, message: t('stockPlaceholder'), trigger: 'blur'},
{
validator: (rule: any, value: string, callback: any) => {
if (value && !/^\d{0,99999}$/.test(value)) {
callback(new Error(t('generateBetween')))
} else {
callback()
}
}
},
]
,
is_show: [
{required: true, message: t('isShowPlaceholder'), trigger: 'blur'},
]
,
is_long_term_valid: [
{required: true, message: t('isLongTermValidPlaceholder'), trigger: 'blur'},
]
,
}
})
const emit = defineEmits(['complete'])
/**
* 确认
* @param formEl
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
let save = formData.id ? editCoupons : addCoupons
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
let data = formData
save(data).then(res => {
loading.value = false
showDialog.value = false
emit('complete')
}).catch(err => {
loading.value = false
})
}
})
}
// 获取字典数据
let is_showList = ref([])
const is_showDictList = async () => {
is_showList.value = await (await useDictionary('is_show_radio')).data.dictionary
}
is_showDictList();
watch(() => is_showList.value, () => {
formData.is_show = is_showList.value[0].value
})
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if (row) {
const data = await (await getCouponsInfo(row.id)).data
if (data) Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
// 验证手机号格式
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
// 验证身份证号
const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
// 验证邮箱号
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
// 验证请输入整数
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

227
admin/src/addon/hygl/views/coupons/coupons.vue

@ -0,0 +1,227 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-lg">{{ pageName }}</span>
<el-button type="primary" @click="addEvent">
{{ t('addCoupons') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="couponsTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('name')" prop="name">
<el-input v-model="couponsTable.searchParam.name" :placeholder="t('namePlaceholder')"/>
</el-form-item>
<el-form-item :label="t('nominalValue')" prop="nominal_value">
<range-input v-model="couponsTable.searchParam.nominal_value"/>
</el-form-item>
<el-form-item :label="t('isShow')" prop="is_show">
<el-select class="w-[280px]" v-model="couponsTable.searchParam.is_show" clearable
:placeholder="t('isShowPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in is_showList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadCouponsList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<div class="mt-[10px]">
<el-table :data="couponsTable.data" size="large" v-loading="couponsTable.loading">
<template #empty>
<span>{{ !couponsTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="name" :label="t('name')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="nominal_value" :label="t('nominalValue')" min-width="120"
:show-overflow-tooltip="true"/>
<el-table-column prop="stock" :label="t('stock')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('isShow')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in is_showList">
<div v-if="item.value == row.is_show">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column :label="t('isObsolete')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in is_showList">
<div v-if="item.value == row.is_obsolete">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column :label="t('isLongTermValid')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in is_showList">
<div v-if="item.value == row.is_long_term_valid">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column :label="t('validTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.valid_time || '' }}
</template>
</el-table-column>
<el-table-column :label="t('createTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.create_time || '' }}
</template>
</el-table-column>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="couponsTable.page" v-model:page-size="couponsTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="couponsTable.total"
@size-change="loadCouponsList()" @current-change="loadCouponsList"/>
</div>
</div>
<edit ref="editCouponsDialog" @complete="loadCouponsList"/>
</el-card>
</div>
</template>
<script lang="ts" setup>
import {reactive, ref, watch} from 'vue'
import {t} from '@/lang'
import {useDictionary} from '@/app/api/dict'
import {getCouponsList, deleteCoupons,} from '@/addon/hygl/api/coupons'
import {img} from '@/utils/common'
import {ElMessageBox, FormInstance} from 'element-plus'
import Edit from '@/addon/hygl/views/coupons/components/coupons-edit.vue'
import {useRoute} from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let couponsTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
"name": "",
"nominal_value": [],
"is_show": ""
}
})
const searchFormRef = ref<FormInstance>()
// 选中数据
const selectData = ref<any[]>([])
// 字典数据
const is_showList = ref([] as any[])
const is_showDictList = async () => {
is_showList.value = await (await useDictionary('is_show_radio')).data.dictionary
}
is_showDictList();
/**
* 获取优惠券列表
*/
const loadCouponsList = (page: number = 1) => {
couponsTable.loading = true
couponsTable.page = page
getCouponsList({
page: couponsTable.page,
limit: couponsTable.limit,
...couponsTable.searchParam
}).then(res => {
couponsTable.loading = false
couponsTable.data = res.data.data
couponsTable.total = res.data.total
}).catch(() => {
couponsTable.loading = false
})
}
loadCouponsList()
const editCouponsDialog: Record<string, any> | null = ref(null)
/**
* 添加优惠券
*/
const addEvent = () => {
editCouponsDialog.value.setFormData()
editCouponsDialog.value.showDialog = true
}
/**
* 编辑优惠券
* @param data
*/
const editEvent = (data: any) => {
editCouponsDialog.value.setFormData(data)
editCouponsDialog.value.showDialog = true
}
/**
* 删除优惠券
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('couponsDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteCoupons(id).then(() => {
loadCouponsList()
}).catch(() => {
})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadCouponsList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

17
admin/src/addon/hygl/views/hello_world/index.vue

@ -0,0 +1,17 @@
<template>
<span class="text-[20px]">{{hello_world_text}}</span>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { getHelloWorld } from '@/addon/hygl/api/hello_world'
const hello_world_text = ref('');
const getHelloWorldInfo = async () => {
hello_world_text.value = await (await getHelloWorld()).data
}
getHelloWorldInfo()
</script>
<style lang="scss" scoped>
</style>

295
admin/src/addon/hygl/views/transaction_history/components/transaction-history-edit.vue

@ -0,0 +1,295 @@
<template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateTransactionHistory') : t('addTransactionHistory')"
width="50%" class="diy-dialog-wrap"
:destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form"
v-loading="loading">
<el-form-item :label="t('userId')" prop="user_id">
<el-input v-model="formData.user_id" clearable :placeholder="t('userIdPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('remark')">
<el-input v-model="formData.remark" clearable :placeholder="t('remarkPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('orderNum')" prop="order_num">
<el-input v-model="formData.order_num" clearable :placeholder="t('orderNumPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('payNum')">
<el-input v-model="formData.pay_num" clearable :placeholder="t('payNumPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('payType')" prop="pay_type">
<el-select class="input-width" v-model="formData.pay_type" clearable :placeholder="t('payTypePlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in pay_typeList"
:key="index"
:label="item['name']"
:value="item['value']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('price')" prop="price">
<el-input-number v-model="formData.price" clearable :placeholder="t('pricePlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('cashFee')">
<el-input-number v-model="formData.cash_fee" clearable :placeholder="t('cashFeePlaceholder')"
class="input-width"/>
</el-form-item>
<el-form-item :label="t('payStatus')" prop="pay_status">
<el-radio-group v-model="formData.pay_status" :placeholder="t('payStatusPlaceholder')">
<el-radio
v-for="(item, index) in pay_statusList"
:key="index"
:label="item.value">
{{ item.name }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('payTime')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.pay_time"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('payTimePlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('payDataJson')">
<el-input v-model="formData.pay_data_json" type="textarea" rows="4" clearable
:placeholder="t('payDataJsonPlaceholder')" class="input-width"/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import {ref, reactive, computed, watch} from 'vue'
import {useDictionary} from '@/app/api/dict'
import {t} from '@/lang'
import type {FormInstance} from 'element-plus'
import {
addTransactionHistory,
editTransactionHistory,
getTransactionHistoryInfo,
} from '@/addon/hygl/api/transaction_history'
let showDialog = ref(false)
const loading = ref(false)
/**
* 表单数据
*/
const initialFormData = {
id: '',
user_id: '',
remark: '',
order_num: '',
pay_num: '',
pay_type: '',
price: '',
cash_fee: '',
pay_status: '0',
pay_time: '',
pay_data_json: '',
}
const formData: Record<string, any> = reactive({...initialFormData})
const formRef = ref<FormInstance>()
// 表单验证规则
const formRules = computed(() => {
return {
user_id: [
{required: true, message: t('userIdPlaceholder'), trigger: 'blur'},
]
,
remark: [
{required: true, message: t('remarkPlaceholder'), trigger: 'blur'},
]
,
order_num: [
{required: true, message: t('orderNumPlaceholder'), trigger: 'blur'},
]
,
pay_num: [
{required: true, message: t('payNumPlaceholder'), trigger: 'blur'},
]
,
pay_type: [
{required: true, message: t('payTypePlaceholder'), trigger: 'blur'},
]
,
price: [
{required: true, message: t('pricePlaceholder'), trigger: 'blur'},
{
validator: (rule: any, value: string, callback: any) => {
if (value && !/^\d{0,99999}$/.test(value)) {
callback(new Error(t('generateBetween')))
} else {
callback()
}
}
},
]
,
cash_fee: [
{required: true, message: t('cashFeePlaceholder'), trigger: 'blur'},
{
validator: (rule: any, value: string, callback: any) => {
if (value && !/^\d{0,99999}$/.test(value)) {
callback(new Error(t('generateBetween')))
} else {
callback()
}
}
},
]
,
pay_status: [
{required: true, message: t('payStatusPlaceholder'), trigger: 'blur'},
]
,
pay_time: [
{required: true, message: t('payTimePlaceholder'), trigger: 'blur'},
]
,
pay_data_json: [
{required: true, message: t('payDataJsonPlaceholder'), trigger: 'blur'},
]
,
}
})
const emit = defineEmits(['complete'])
/**
* 确认
* @param formEl
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
let save = formData.id ? editTransactionHistory : addTransactionHistory
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
let data = formData
save(data).then(res => {
loading.value = false
showDialog.value = false
emit('complete')
}).catch(err => {
loading.value = false
})
}
})
}
// 获取字典数据
let pay_typeList = ref([])
const pay_typeDictList = async () => {
pay_typeList.value = await (await useDictionary('pay_type')).data.dictionary
}
pay_typeDictList();
watch(() => pay_typeList.value, () => {
formData.pay_type = pay_typeList.value[0].value
})
let pay_statusList = ref([])
const pay_statusDictList = async () => {
pay_statusList.value = await (await useDictionary('is_show_radio')).data.dictionary
}
pay_statusDictList();
watch(() => pay_statusList.value, () => {
formData.pay_status = pay_statusList.value[0].value
})
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if (row) {
const data = await (await getTransactionHistoryInfo(row.id)).data
if (data) Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
// 验证手机号格式
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
// 验证身份证号
const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
// 验证邮箱号
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
// 验证请输入整数
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

286
admin/src/addon/hygl/views/transaction_history/transaction_history.vue

@ -0,0 +1,286 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<!-- <span class="text-lg">{{ pageName }}</span>-->
<!-- <el-button type="primary" @click="addEvent">-->
<!-- {{ t('addTransactionHistory') }}-->
<!-- </el-button>-->
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="transactionHistoryTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('userId')" prop="user_id">
<el-input v-model="transactionHistoryTable.searchParam.user_id" :placeholder="t('userIdPlaceholder')"/>
</el-form-item>
<el-form-item :label="t('orderNum')" prop="order_num">
<el-input v-model="transactionHistoryTable.searchParam.order_num" :placeholder="t('orderNumPlaceholder')"/>
</el-form-item>
<el-form-item :label="t('payNum')" prop="pay_num">
<el-input v-model="transactionHistoryTable.searchParam.pay_num" :placeholder="t('payNumPlaceholder')"/>
</el-form-item>
<el-form-item :label="t('payType')" prop="pay_type">
<el-select class="w-[280px]" v-model="transactionHistoryTable.searchParam.pay_type" clearable
:placeholder="t('payTypePlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in pay_typeList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('price')" prop="price">
<range-input v-model="transactionHistoryTable.searchParam.price"/>
</el-form-item>
<el-form-item :label="t('cashFee')" prop="cash_fee">
<range-input v-model="transactionHistoryTable.searchParam.cash_fee"/>
</el-form-item>
<el-form-item :label="t('payStatus')" prop="pay_status">
<el-select class="w-[280px]" v-model="transactionHistoryTable.searchParam.pay_status" clearable
:placeholder="t('payStatusPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in pay_statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('payTime')" prop="pay_time">
<el-date-picker v-model="transactionHistoryTable.searchParam.pay_time" type="daterange"
value-format="YYYY-MM-DD"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')"/>
</el-form-item>
<el-form-item :label="t('createTime')" prop="create_time">
<el-date-picker v-model="transactionHistoryTable.searchParam.create_time" type="daterange"
value-format="YYYY-MM-DD"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadTransactionHistoryList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<div class="mt-[10px]">
<el-table :data="transactionHistoryTable.data" size="large" v-loading="transactionHistoryTable.loading">
<template #empty>
<span>{{ !transactionHistoryTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="user_id" :label="t('userId')" min-width="120" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.user && row.user.name ? row.user.name + `#` + row.user.id : '顶级' }}
</template>
</el-table-column>
<!-- <el-table-column prop="remark" :label="t('remark')" min-width="120" :show-overflow-tooltip="true"/>-->
<el-table-column prop="order_num" :label="t('orderNum')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="pay_num" :label="t('payNum')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('payType')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in pay_typeList">
<div v-if="item.value == row.pay_type">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column prop="price" :label="t('price')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('couponsInfo')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.userCoupons && row.userCoupons.coupons ? row.userCoupons.coupons.name : '' }}
</template>
</el-table-column>
<el-table-column prop="cash_fee" :label="t('cashFee')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('payStatus')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in pay_statusList">
<div v-if="item.value == row.pay_status">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column :label="t('payTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.pay_time || '' }}
</template>
</el-table-column>
<!--
<el-table-column prop="pay_data_json" :label="t('payDataJson')" min-width="120"
:show-overflow-tooltip="true"/>
-->
<el-table-column :label="t('createTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.create_time || '' }}
</template>
</el-table-column>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
<!-- <el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>-->
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="transactionHistoryTable.page"
v-model:page-size="transactionHistoryTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="transactionHistoryTable.total"
@size-change="loadTransactionHistoryList()" @current-change="loadTransactionHistoryList"/>
</div>
</div>
<edit ref="editTransactionHistoryDialog" @complete="loadTransactionHistoryList"/>
</el-card>
</div>
</template>
<script lang="ts" setup>
import {reactive, ref, watch} from 'vue'
import {t} from '@/lang'
import {useDictionary} from '@/app/api/dict'
import {getTransactionHistoryList, deleteTransactionHistory,} from '@/addon/hygl/api/transaction_history'
import {img} from '@/utils/common'
import {ElMessageBox, FormInstance} from 'element-plus'
import Edit from '@/addon/hygl/views/transaction_history/components/transaction-history-edit.vue'
import {useRoute} from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let transactionHistoryTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
"user_id": "",
"order_num": "",
"pay_num": "",
"pay_type": "",
"price": [],
"cash_fee": [],
"pay_status": "",
"pay_time": [],
"create_time": []
}
})
const searchFormRef = ref<FormInstance>()
// 选中数据
const selectData = ref<any[]>([])
// 字典数据
const pay_typeList = ref([] as any[])
const pay_typeDictList = async () => {
pay_typeList.value = await (await useDictionary('pay_type')).data.dictionary
}
pay_typeDictList();
const pay_statusList = ref([] as any[])
const pay_statusDictList = async () => {
pay_statusList.value = await (await useDictionary('is_show_radio')).data.dictionary
}
pay_statusDictList();
/**
* 获取会员交易记录列表
*/
const loadTransactionHistoryList = (page: number = 1) => {
transactionHistoryTable.loading = true
transactionHistoryTable.page = page
getTransactionHistoryList({
page: transactionHistoryTable.page,
limit: transactionHistoryTable.limit,
...transactionHistoryTable.searchParam
}).then(res => {
transactionHistoryTable.loading = false
transactionHistoryTable.data = res.data.data
transactionHistoryTable.total = res.data.total
}).catch(() => {
transactionHistoryTable.loading = false
})
}
loadTransactionHistoryList()
const editTransactionHistoryDialog: Record<string, any> | null = ref(null)
/**
* 添加会员交易记录
*/
const addEvent = () => {
editTransactionHistoryDialog.value.setFormData()
editTransactionHistoryDialog.value.showDialog = true
}
/**
* 编辑会员交易记录
* @param data
*/
const editEvent = (data: any) => {
editTransactionHistoryDialog.value.setFormData(data)
editTransactionHistoryDialog.value.showDialog = true
}
/**
* 删除会员交易记录
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('transactionHistoryDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteTransactionHistory(id).then(() => {
loadTransactionHistoryList()
}).catch(() => {
})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadTransactionHistoryList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

311
admin/src/addon/hygl/views/user/components/user-edit.vue

@ -0,0 +1,311 @@
<template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateUser') : t('addUser')" width="50%"
class="diy-dialog-wrap"
:destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form"
v-loading="loading">
<el-form-item :label="t('tel')" prop="tel">
<el-input v-model="formData.tel" clearable :placeholder="t('telPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('name')" prop="name">
<el-input v-model="formData.name" clearable :placeholder="t('namePlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('pic')">
<upload-image v-model="formData.pic"/>
</el-form-item>
<el-form-item :label="t('password')">
<el-input v-model="formData.password" clearable :placeholder="t('passwordPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('pid')" prop="pid">
<el-select class="input-width" v-model="formData.pid" clearable :placeholder="t('pidPlaceholder')">
<el-option label="顶级" :value="0"></el-option>
<el-option
v-for="(item, index) in pidList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<!-- <el-form-item :label="t('level')" prop="level">-->
<!-- <el-input v-model="formData.level" clearable :placeholder="t('levelPlaceholder')" class="input-width"/>-->
<!-- </el-form-item>-->
<el-form-item :label="t('wxOpenid')" v-show="!formData.id">
<el-input v-model="formData.wx_openid" clearable :placeholder="t('wxOpenidPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('wxUnionid')" v-show="!formData.id">
<el-input v-model="formData.wx_unionid" clearable :placeholder="t('wxUnionidPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('sex')" prop="sex">
<el-radio-group v-model="formData.sex" :placeholder="t('sexPlaceholder')">
<el-radio
v-for="(item, index) in sexList"
:key="index"
:label="item.value">
{{ item.name }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('birthday')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.birthday"
clearable
type="date"
value-format="YYYY-MM-DD"
:placeholder="t('birthdayPlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('isShow')" prop="is_show">
<el-radio-group v-model="formData.is_show" :placeholder="t('isShowPlaceholder')">
<el-radio
v-for="(item, index) in is_showList"
:key="index"
:label="item.value">
{{ item.name }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import {ref, reactive, computed, watch} from 'vue'
import {useDictionary} from '@/app/api/dict'
import {t} from '@/lang'
import type {FormInstance} from 'element-plus'
import {addUser, editUser, getUserInfo, getWithUserList,} from '@/addon/hygl/api/user'
let showDialog = ref(false)
const loading = ref(false)
/**
* 表单数据
*/
const initialFormData = {
id: '',
tel: '',
name: '',
pic: '',
password: '',
pid: 0,
// level: '',
wx_openid: '',
wx_unionid: '',
sex: '1',
birthday: '',
is_show: '1',
}
const formData: Record<string, any> = reactive({...initialFormData})
const formRef = ref<FormInstance>()
// 表单验证规则
const formRules = computed(() => {
return {
tel: [
{required: true, message: t('telPlaceholder'), trigger: 'blur'},
]
,
name: [
{required: true, message: t('namePlaceholder'), trigger: 'blur'},
]
,
pic: [
{required: true, message: t('picPlaceholder'), trigger: 'blur'},
]
,
password: [
{required: true, message: t('passwordPlaceholder'), trigger: 'blur'},
]
,
pid: [
{required: true, message: t('pidPlaceholder'), trigger: 'blur'},
]
,
level: [
{required: true, message: t('levelPlaceholder'), trigger: 'blur'},
]
,
wx_openid: [
{required: true, message: t('wxOpenidPlaceholder'), trigger: 'blur'},
]
,
wx_unionid: [
{required: true, message: t('wxUnionidPlaceholder'), trigger: 'blur'},
]
,
sex: [
{required: true, message: t('sexPlaceholder'), trigger: 'blur'},
]
,
birthday: [
{required: true, message: t('birthdayPlaceholder'), trigger: 'blur'},
]
,
is_show: [
{required: true, message: t('isShowPlaceholder'), trigger: 'blur'},
]
,
}
})
const emit = defineEmits(['complete'])
/**
* 确认
* @param formEl
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
let save = formData.id ? editUser : addUser
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
let data = formData
save(data).then(res => {
loading.value = false
showDialog.value = false
emit('complete')
}).catch(err => {
loading.value = false
})
}
})
}
// 获取字典数据
let site_idList = ref([])
const site_idDictList = async () => {
site_idList.value = await (await useDictionary('placeholder_')).data.dictionary
}
site_idDictList();
watch(() => site_idList.value, () => {
formData.site_id = site_idList.value[0].value
})
//获取全部用户列表
const pidList = ref([] as any[])
const setPidList = async () => {
pidList.value = await (await getWithUserList({})).data.data
}
setPidList()
let sexList = ref([])
const sexDictList = async () => {
sexList.value = await (await useDictionary('sex_radio')).data.dictionary
}
sexDictList();
watch(() => sexList.value, () => {
formData.sex = sexList.value[0].value
})
let is_showList = ref([])
const is_showDictList = async () => {
is_showList.value = await (await useDictionary('is_show_radio')).data.dictionary
}
is_showDictList();
watch(() => is_showList.value, () => {
formData.is_show = is_showList.value[0].value
})
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if (row) {
const data = await (await getUserInfo(row.id)).data
if (data) Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined){
formData[key] = data[key]
// 过滤掉当前用户列表(把自己过滤出去)
}
})
}
loading.value = false
}
// 验证手机号格式
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
// 验证身份证号
const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
// 验证邮箱号
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
// 验证请输入整数
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

283
admin/src/addon/hygl/views/user/user.vue

@ -0,0 +1,283 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-lg">{{ pageName }}</span>
<el-button type="primary" @click="addEvent">
{{ t('addUser') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="userTable.searchParam" ref="searchFormRef">
<!-- <el-form-item :label="t('siteId')" prop="site_id">-->
<!-- <el-select class="w-[280px]" v-model="userTable.searchParam.site_id" clearable-->
<!-- :placeholder="t('siteIdPlaceholder')">-->
<!-- <el-option label="全部" value=""></el-option>-->
<!-- <el-option-->
<!-- v-for="(item, index) in site_idList"-->
<!-- :key="index"-->
<!-- :label="item.name"-->
<!-- :value="item.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item :label="t('tel')" prop="tel">
<el-input v-model="userTable.searchParam.tel" :placeholder="t('telPlaceholder')"/>
</el-form-item>
<el-form-item :label="t('name')" prop="name">
<el-input v-model="userTable.searchParam.name" :placeholder="t('namePlaceholder')"/>
</el-form-item>
<!-- <el-form-item :label="t('password')" prop="password">-->
<!-- <el-input v-model="userTable.searchParam.password" :placeholder="t('passwordPlaceholder')"/>-->
<!-- </el-form-item>-->
<el-form-item :label="t('sex')" prop="sex">
<el-select class="w-[280px]" v-model="userTable.searchParam.sex" clearable
:placeholder="t('sexPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in sexList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('birthday')" prop="birthday">
<el-date-picker v-model="userTable.searchParam.birthday" type="daterange"
value-format="YYYY-MM-DD"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')"/>
</el-form-item>
<el-form-item :label="t('isShow')" prop="is_show">
<el-select class="w-[280px]" v-model="userTable.searchParam.is_show" clearable
:placeholder="t('isShowPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in is_showList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadUserList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<div class="mt-[10px]">
<el-table :data="userTable.data" size="large" v-loading="userTable.loading">
<template #empty>
<span>{{ !userTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="60" :show-overflow-tooltip="true"/>
<el-table-column prop="tel" :label="t('tel')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="name" :label="t('name')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('pic')" width="100" align="left">
<template #default="{ row }">
<el-avatar v-if="row.pic" :src="img(row.pic)"/>
<el-avatar v-else icon="UserFilled"/>
</template>
</el-table-column>
<!-- <el-table-column prop="password" :label="t('password')" min-width="120" :show-overflow-tooltip="true"/>-->
<el-table-column :label="t('pid')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.user && row.user.name ? row.user.name + `#` + row.user.id : '顶级' }}
</template>
</el-table-column>
<el-table-column prop="level" :label="t('level')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="wx_openid" :label="t('wxOpenid')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="wx_unionid" :label="t('wxUnionid')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('sex')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in sexList">
<div v-if="item.value == row.sex">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column prop="birthday" :label="t('birthday')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('isShow')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in is_showList">
<div v-if="item.value == row.is_show">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column :label="t('createTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.create_time || '' }}
</template>
</el-table-column>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="userTable.page" v-model:page-size="userTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="userTable.total"
@size-change="loadUserList()" @current-change="loadUserList"/>
</div>
</div>
<edit ref="editUserDialog" @complete="loadUserList"/>
</el-card>
</div>
</template>
<script lang="ts" setup>
import {reactive, ref, watch} from 'vue'
import {t} from '@/lang'
import {useDictionary} from '@/app/api/dict'
import {getUserList, deleteUser,} from '@/addon/hygl/api/user'
import {img} from '@/utils/common'
import {ElMessageBox, FormInstance} from 'element-plus'
import Edit from '@/addon/hygl/views/user/components/user-edit.vue'
import {useRoute} from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let userTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
"site_id": "",
"tel": "",
"name": "",
"password": "",
"sex": "",
"birthday": [],
"is_show": ""
}
})
const searchFormRef = ref<FormInstance>()
// 选中数据
const selectData = ref<any[]>([])
// 字典数据
const site_idList = ref([] as any[])
const site_idDictList = async () => {
site_idList.value = await (await useDictionary('placeholder_')).data.dictionary
}
site_idDictList();
const sexList = ref([] as any[])
const sexDictList = async () => {
sexList.value = await (await useDictionary('sex_radio')).data.dictionary
}
sexDictList();
const is_showList = ref([] as any[])
const is_showDictList = async () => {
is_showList.value = await (await useDictionary('is_show_radio')).data.dictionary
}
is_showDictList();
/**
* 获取会员管理列表
*/
const loadUserList = (page: number = 1) => {
userTable.loading = true
userTable.page = page
getUserList({
page: userTable.page,
limit: userTable.limit,
...userTable.searchParam
}).then(res => {
userTable.loading = false
userTable.data = res.data.data
userTable.total = res.data.total
}).catch(() => {
userTable.loading = false
})
}
loadUserList()
const editUserDialog: Record<string, any> | null = ref(null)
/**
* 添加会员管理
*/
const addEvent = () => {
editUserDialog.value.setFormData()
editUserDialog.value.showDialog = true
}
/**
* 编辑会员管理
* @param data
*/
const editEvent = (data: any) => {
editUserDialog.value.setFormData(data)
editUserDialog.value.showDialog = true
}
/**
* 删除会员管理
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('userDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteUser(id).then(() => {
loadUserList()
}).catch(() => {
})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadUserList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

233
admin/src/addon/hygl/views/user_coupons/components/user-coupons-edit.vue

@ -0,0 +1,233 @@
<template>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateUserCoupons') : t('addUserCoupons')" width="50%"
class="diy-dialog-wrap"
:destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form"
v-loading="loading">
<el-form-item :label="t('userId')" prop="user_id">
<el-select class="input-width" v-model="formData.user_id" clearable :placeholder="t('userIdPlaceholder')" filterable>
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in userIdList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('couponsId')" prop="coupons_id">
<el-select class="input-width" v-model="formData.coupons_id" clearable :placeholder="t('couponsIdPlaceholder')" filterable>
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in nameList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<!--
<el-form-item :label="t('nominalValue')" prop="nominal_value">
<el-input-number v-model="formData.nominal_value" clearable :placeholder="t('nominalValuePlaceholder')"
class="input-width"/>
</el-form-item>
-->
<el-form-item :label="t('isShow')" prop="is_show">
<el-radio-group v-model="formData.is_show" :placeholder="t('isShowPlaceholder')">
<el-radio
v-for="(item, index) in is_showList"
:key="index"
:label="item.value">
{{ item.name }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import {ref, reactive, computed, watch} from 'vue'
import {useDictionary} from '@/app/api/dict'
import {t} from '@/lang'
import type {FormInstance} from 'element-plus'
import {addUserCoupons, editUserCoupons, getUserCouponsInfo, getWithUserList,} from '@/addon/hygl/api/user_coupons'
import {getWithCouponsList} from "@/addon/hygl/api/common";
let showDialog = ref(false)
const loading = ref(false)
/**
* 表单数据
*/
const initialFormData = {
id: '',
user_id: '',
coupons_id: '',
is_show: '1',
}
const formData: Record<string, any> = reactive({...initialFormData})
const formRef = ref<FormInstance>()
// 表单验证规则
const formRules = computed(() => {
return {
user_id: [
{required: true, message: t('userIdPlaceholder'), trigger: 'blur'},
]
,
coupons_id: [
{required: true, message: t('couponsIdPlaceholder'), trigger: 'blur'},
]
,
nominal_value: [
{required: true, message: t('nominalValuePlaceholder'), trigger: 'blur'},
{
validator: (rule: any, value: string, callback: any) => {
if (value && !/^\d{0,99999}$/.test(value)) {
callback(new Error(t('generateBetween')))
} else {
callback()
}
}
},
]
,
is_show: [
{required: true, message: t('isShowPlaceholder'), trigger: 'blur'},
]
,
}
})
const emit = defineEmits(['complete'])
/**
* 确认
* @param formEl
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
let save = formData.id ? editUserCoupons : addUserCoupons
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
let data = formData
save(data).then(res => {
loading.value = false
showDialog.value = false
emit('complete')
}).catch(err => {
loading.value = false
})
}
})
}
// 获取字典数据
//获取优惠券远程下拉菜单列表
const nameList = ref([] as any[])
const setNameList = async () => {
nameList.value = await (await getWithCouponsList({'name':''})).data
}
setNameList()
let is_showList = ref([])
const is_showDictList = async () => {
is_showList.value = await (await useDictionary('is_show_radio')).data.dictionary
}
is_showDictList();
watch(() => is_showList.value, () => {
formData.is_show = is_showList.value[0].value
})
const userIdList = ref([] as any[])
const setUserIdList = async () => {
userIdList.value = await (await getWithUserList({})).data.data
}
setUserIdList()
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if (row) {
const data = await (await getUserCouponsInfo(row.id)).data
if (data) Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
loading.value = false
}
// 验证手机号格式
const mobileVerify = (rule: any, value: any, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
// 验证身份证号
const idCardVerify = (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
}
// 验证邮箱号
const emailVerify = (rule: any, value: any, callback: any) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
}
// 验证请输入整数
const numberVerify = (rule: any, value: any, callback: any) => {
if (!Number.isInteger(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
}
defineExpose({
showDialog,
setFormData
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

249
admin/src/addon/hygl/views/user_coupons/user_coupons.vue

@ -0,0 +1,249 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-lg">{{ pageName }}</span>
<el-button type="primary" @click="addEvent">
{{ t('addUserCoupons') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="userCouponsTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('userId')" prop="user_id">
<el-select class="w-[280px]" v-model="userCouponsTable.searchParam.user_id" clearable
:placeholder="t('userIdPlaceholder')">
<el-option
v-for="(item, index) in userIdList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<!-- <el-form-item :label="t('siteId')" prop="site_id">-->
<!-- <el-input v-model="userCouponsTable.searchParam.site_id" :placeholder="t('siteIdPlaceholder')"/>-->
<!-- </el-form-item>-->
<el-form-item :label="t('couponsId')" prop="name">
<el-input v-model="userCouponsTable.searchParam.coupons_id" :placeholder="t('couponsIdPlaceholder')"/>
</el-form-item>
<el-form-item :label="t('nominalValue')" prop="nominal_value">
<range-input v-model="userCouponsTable.searchParam.nominal_value"/>
</el-form-item>
<el-form-item :label="t('isShow')" prop="is_show">
<el-select class="w-[280px]" v-model="userCouponsTable.searchParam.is_show" clearable
:placeholder="t('isShowPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in is_showList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('createTime')" prop="create_time">
<el-date-picker v-model="userCouponsTable.searchParam.create_time" type="datetimerange"
format="YYYY-MM-DD hh:mm:ss"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadUserCouponsList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<div class="mt-[10px]">
<el-table :data="userCouponsTable.data" size="large" v-loading="userCouponsTable.loading">
<template #empty>
<span>{{ !userCouponsTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="user_id" :label="t('userId')" min-width="120" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.user && row.user.name ? row.user.name : '' }}
</template>
</el-table-column>
<el-table-column prop="coupons_id" :label="t('couponsId')" min-width="120" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.coupons && row.coupons.name ? row.coupons.name : '' }}
</template>
</el-table-column>
<el-table-column prop="nominal_value" :label="t('nominalValue')" min-width="120"
:show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.coupons && row.coupons.nominal_value ? row.coupons.nominal_value : '0' }}
</template>
</el-table-column>
<el-table-column prop="valid_time" :label="t('validTime')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('isShow')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in is_showList">
<div v-if="item.value == row.is_show">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column :label="t('createTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.create_time || '' }}
</template>
</el-table-column>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
<!-- <el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>-->
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="userCouponsTable.page" v-model:page-size="userCouponsTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="userCouponsTable.total"
@size-change="loadUserCouponsList()" @current-change="loadUserCouponsList"/>
</div>
</div>
<edit ref="editUserCouponsDialog" @complete="loadUserCouponsList"/>
</el-card>
</div>
</template>
<script lang="ts" setup>
import {reactive, ref, watch} from 'vue'
import {t} from '@/lang'
import {useDictionary} from '@/app/api/dict'
import {getUserCouponsList, deleteUserCoupons, getWithUserList,} from '@/addon/hygl/api/user_coupons'
import {img} from '@/utils/common'
import {ElMessageBox, FormInstance} from 'element-plus'
import Edit from '@/addon/hygl/views/user_coupons/components/user-coupons-edit.vue'
import {useRoute} from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let userCouponsTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
"user_id": "",
"site_id": "",
"coupons_id": "",
"nominal_value": [],
"is_show": "",
"create_time": []
}
})
const searchFormRef = ref<FormInstance>()
// 选中数据
const selectData = ref<any[]>([])
// 字典数据
const is_showList = ref([] as any[])
const is_showDictList = async () => {
is_showList.value = await (await useDictionary('is_show_radio')).data.dictionary
}
is_showDictList();
/**
* 获取用户优惠券列表
*/
const loadUserCouponsList = (page: number = 1) => {
userCouponsTable.loading = true
userCouponsTable.page = page
getUserCouponsList({
page: userCouponsTable.page,
limit: userCouponsTable.limit,
...userCouponsTable.searchParam
}).then(res => {
userCouponsTable.loading = false
userCouponsTable.data = res.data.data
userCouponsTable.total = res.data.total
}).catch(() => {
userCouponsTable.loading = false
})
}
loadUserCouponsList()
const editUserCouponsDialog: Record<string, any> | null = ref(null)
/**
* 添加用户优惠券
*/
const addEvent = () => {
editUserCouponsDialog.value.setFormData()
editUserCouponsDialog.value.showDialog = true
}
/**
* 编辑用户优惠券
* @param data
*/
const editEvent = (data: any) => {
editUserCouponsDialog.value.setFormData(data)
editUserCouponsDialog.value.showDialog = true
}
/**
* 删除用户优惠券
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('userCouponsDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteUserCoupons(id).then(() => {
loadUserCouponsList()
}).catch(() => {
})
})
}
const userIdList = ref([])
const setUserIdList = async () => {
userIdList.value = await (await getWithUserList({})).data
}
setUserIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadUserCouponsList()
}
</script>
<style lang="scss" scoped>
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>

92
admin/src/app/api/addon.ts

@ -0,0 +1,92 @@
import request from '@/utils/request'
/**
* 本地下载的插件列表
* @returns
*/
export function getAddonLocal(params: Record<string, any>) {
return request.get('addon/local', params, { showSuccessMessage: true })
}
/**
* 插件详情
* @returns
*/
export function getAddonDetial(id: number) {
return request.get(`addon/${id}`)
}
/**
* 安装插件
* @param params
* @returns
*/
export function installAddon(params: Record<string, any>) {
return request.post(`addon/install/${params.addon}`, params)
}
/**
* 安装插件
* @param params
* @returns
*/
export function cloudInstallAddon(params: Record<string, any>) {
return request.post(`addon/cloudinstall/${params.addon}`, params, { timeout: 60 * 1000 })
}
/**
* 卸载插件
* @param params
* @returns
*/
export function uninstallAddon(params: Record<string, any>) {
return request.post(`addon/uninstall/${params.addon}`, params, { showSuccessMessage: true })
}
/**
* 插件安装前检测
* @param addon
* @returns
*/
export function preInstallCheck(addon: string) {
return request.get(`addon/install/check/${addon}`, { timeout: 30 * 1000 })
}
/**
* 获取正在安装的插件
* @returns
*/
export function getAddonInstalltask() {
return request.get('addon/installtask')
}
/**
* 获取插件云安装日志
* @param addon
* @returns
*/
export function getAddonCloudInstallLog(addon: string) {
return request.get(`addon/cloudinstall/${addon}`)
}
/**
* 插件卸载前检测
* @param addon
* @returns
*/
export function preUninstallCheck(addon: string) {
return request.get(`addon/uninstall/check/${addon}`, { timeout: 30 * 1000 })
}
/**
* 取消插件安装
* @param addon
* @returns
*/
export function cancelInstall(addon: string) {
return request.put(`addon/install/cancel/${addon}`, {}, { showErrorMessage: false })
}
export function getInstalledAddonList() {
return request.get('addon/list/install')
}

26
admin/src/app/api/aliapp.ts

@ -0,0 +1,26 @@
import request from '@/utils/request'
/**
* 获取支付宝小程序配置
* @returns
*/
export function getAliappConfig() {
return request.get('aliapp/config')
}
/**
* 编辑支付宝小程序配置
* @param params
* @returns
*/
export function setAliappConfig(params: Record<string, any>) {
return request.put('aliapp/config', params, {showSuccessMessage: true})
}
/**
* 获取支付宝小程序静态资源
* @returns
*/
export function getAliappStatic() {
return request.get('aliapp/static')
}

48
admin/src/app/api/auth.ts

@ -0,0 +1,48 @@
import request from '@/utils/request'
/**
* 登录
* @param params
* @param app_type
*/
export function login(params: Record<string, any>, app_type: string) {
return request.get(`login/${app_type}`, {params})
}
/**
* 退出登录
*/
export function logout() {
return request.put('auth/logout', {}, { showErrorMessage: false })
}
/**
* 获取登录用户权限
* @returns
*/
export function getAuthMenus(params: Record<string, any>) {
return request.get('auth/authmenu', {params})
}
/**
* 获取登录用户权限
* @returns
*/
export function getSiteInfo() {
return request.get('auth/site')
}
/**
* 获取登录配置信息
* @returns
*/
export function getLoginConfig() {
return request.get('login/config')
}
/**
* 获取当前版本信息
*/
export function getVersions() {
return request.get(`sys/info`)
}

38
admin/src/app/api/cloud.ts

@ -0,0 +1,38 @@
import request from '@/utils/request'
/**
* 云编译
* @param addon
*/
export function cloudBuild() {
return request.post('niucloud/build', {}, { timeout: 0 })
}
/**
* 获取云编译任务
* @param addon
*/
export function getCloudBuildTask() {
return request.get('niucloud/build')
}
/**
* 云编译前检测
*/
export function getCloudBuildLog() {
return request.get('niucloud/build/log')
}
/**
* 清除
*/
export function clearCloudBuildTask() {
return request.post('niucloud/build/clear')
}
/**
* 云编译前检测
*/
export function preBuildCheck() {
return request.get('niucloud/build/check')
}

81
admin/src/app/api/dict.ts

@ -0,0 +1,81 @@
import request from '@/utils/request'
/**
* 获取数据字典列表
* @param params
* @returns
*/
export function getDictList(params: Record<string, any>) {
return request.get(`dict/dict`, {params})
}
/**
* 获取数据字典详情
* @param id 数据字典id
* @returns
*/
export function getDictInfo(id: number) {
return request.get(`dict/dict/${id}`);
}
/**
* 添加数据字典
* @param params
* @returns
*/
export function addDict(params: Record<string, any>) {
return request.post('dict/dict', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 编辑数据字典
* @param params
* @returns
*/
export function addDictData(params: Record<string, any>) {
return request.put(`dict/dict/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 编辑数据字典
* @param params
* @returns
*/
export function editDict(params: Record<string, any>) {
return request.put(`dict/dict/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 删除数据字典
* @param id
* @returns
*/
export function deleteDict(id: number) {
return request.delete(`dict/dict/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* 编辑数据字典内容
* @param id
* @param params
* @returns
*/
export function setDictData(id:number,params: Record<string, any>) {
return request.put(`dict/dictionary/${id}`, params, { showErrorMessage: true,showSuccessMessage: true })
}
/**
* 获取数据字典列表全部
* @returns
*/
export function getDictAll() {
return request.get(`dict/all`)
}
/**
* 数据字典关键词查询
* @param type
* @returns
*/
export function useDictionary(type: string) {
return request.get(`dict/dictionary/type/${type}`)
}

183
admin/src/app/api/diy.ts

@ -0,0 +1,183 @@
import request from '@/utils/request'
/***************************************************** 自定义页面 ****************************************************/
/**
* 获取自定义页面分页列表
* @param params
* @returns
*/
export function getDiyPageList(params: Record<string, any>) {
return request.get(`diy/diy`, {params})
}
/**
* 获取自定义页面列表
* @param params
* @returns
*/
export function getDiyList(params: Record<string, any>) {
return request.get(`diy/list`, {params})
}
/**
* 获取自定义页面详情
* @param id 自定义页面id
* @returns
*/
export function getDiyPageInfo(id: number) {
return request.get(`diy/diy/${id}`);
}
/**
* 添加自定义页面
* @param params
* @returns
*/
export function addDiyPage(params: Record<string, any>) {
return request.post('diy/diy', params, {showSuccessMessage: true})
}
/**
* 编辑自定义页面
* @param params
*/
export function editDiyPage(params: Record<string, any>) {
return request.put(`diy/diy/${params.id}`, params, {showSuccessMessage: true})
}
/**
* 设为使用
* @param params
*/
export function setUseDiyPage(params: Record<string, any>) {
return request.put(`diy/use`, params, {showSuccessMessage: true})
}
/**
* 修改自定义页面分享内容
* @param params
*/
export function editDiyPageShare(params: Record<string, any>) {
return request.put(`diy/diy/share`, params, {showSuccessMessage: true})
}
/**
* 删除自定义页面
* @param id
* @returns
*/
export function deleteDiyPage(id: number) {
return request.delete(`diy/diy/${id}`, {showSuccessMessage: true})
}
/**
* 获取自定义页面初始化数据
*/
export function initPage(params: Record<string, any>) {
return request.get(`diy/init`, {params})
}
/**
* 获取自定义链接列表
*/
export function getLink(params: Record<string, any>) {
return request.get(`diy/link`, {params})
}
/**
* 获取底部导航列表
*/
export function getDiyBottomList(params: Record<string, any>) {
return request.get(`diy/bottom`, {params})
}
/**
* 获取底部导航数据
*/
export function getDiyBottomConfig(params: Record<string, any>) {
return request.get(`diy/bottom/config`, {params})
}
/**
* 设置底部导航数据
* @param params
* @returns
*/
export function setDiyBottomConfig(params: Record<string, any>) {
return request.post('diy/bottom', params, {showSuccessMessage: true})
}
/**
* 获取页面模板类型
*/
export function getDiyTemplate(params: Record<string, any>) {
return request.get(`diy/template`, {params})
}
/**
* 获取模板页面列表
*/
export function getDiyTemplatePages(params: Record<string, any>) {
return request.get(`diy/template/pages`, {params})
}
/**
* 获取自定义路由列表
* @param params
* @returns
*/
export function getDiyRouteList(params: Record<string, any>) {
return request.get(`diy/route`, {params})
}
/**
* 获取路由列表(存在的应用插件列表)
* @returns
*/
export function getDiyRouteAppList() {
return request.get(`diy/route/apps`)
}
/**
* 获取自定义路由信息
* @param params
*/
export function getDiyRouteInfo(params: Record<string, any>) {
return request.get(`diy/route/info`, {params});
}
/**
* 修改路由页面分享内容
* @param params
*/
export function editDiyRouteShare(params: Record<string, any>) {
return request.put(`diy/route/share`, params, {showSuccessMessage: true})
}
/**
* 获取自定义页面列表
* @param params
* @returns
*/
export function getDecoratePage(params: Record<string, any>) {
return request.get(`diy/decorate`, {params})
}
/**
* 切换模板
* @param params
* @returns
*/
export function changeTemplate(params: Record<string, any>) {
return request.put(`diy/change`, params, {showSuccessMessage: true})
}
/**
* 获取模板页面(存在的应用插件列表)
* @param params
* @returns
*/
export function getApps(params: Record<string, any>) {
return request.get(`diy/apps`)
}

18
admin/src/app/api/h5.ts

@ -0,0 +1,18 @@
import request from '@/utils/request'
/**
* 获取h5配置
* @returns
*/
export function getH5Config() {
return request.get('channel/h5/config')
}
/**
* 编辑h5配置
* @param params
* @returns
*/
export function setH5Config(params: Record<string, any>) {
return request.put('channel/h5/config', params, {showSuccessMessage: true})
}

5
admin/src/app/api/home.ts

@ -0,0 +1,5 @@
import request from '@/utils/request'
export function getHomeSite(params: Record<string, any>) {
return request.get(`home/site`, { params })
}

354
admin/src/app/api/member.ts

@ -0,0 +1,354 @@
import request from '@/utils/request'
/***************************************************** 会员管理 ****************************************************/
/**
* 获取会员列表
* @param params
* @returns
*/
export function getMemberList(params: Record<string, any>) {
return request.get(`member/member`, {params})
}
/**
* 获取会员详情
* @param id 会员id
* @returns
*/
export function getMemberInfo(id: number) {
return request.get(`member/member/${id}`);
}
/**
* 获取会员编码
* @returns
*/
export function getMemberNo() {
return request.get(`member/memberno`);
}
/**
* 添加会员
* @param params
* @returns
*/
export function addMember(params: Record<string, any>) {
return request.post(`member/member`, params, {showSuccessMessage: true})
}
/**
* 会员注册方式
* @param params
* @returns
*/
export function getRegisterType(params: Record<string, any>) {
return request.get(`member/registertype`, params)
}
/**
* 会员注册渠道
* @param params
* @returns
*/
export function getRegisterChannelType(params: Record<string, any>) {
return request.get(`member/register/channel`, params)
}
/**
* 会员删除
* @param member_id
*/
export function deleteMember(member_id: number) {
return request.delete(`member/member/${member_id}`, {showSuccessMessage: true})
}
/***************************************************** 会员标签 ****************************************************/
/**
* 获取会员标签列表
* @param params
* @returns
*/
export function getMemberLabelList(params: Record<string, any>) {
return request.get(`member/label`, {params})
}
/**
* 获取会员标签详情
* @param label_id 会员标签label_id
* @returns
*/
export function getMemberLabelInfo(label_id: number) {
return request.get(`member/label/${label_id}`);
}
/**
* 添加会员标签
* @param params
* @returns
*/
export function addMemberLabel(params: Record<string, any>) {
return request.post('member/label', params, {showSuccessMessage: true})
}
/**
* 编辑会员标签
* @param params
*/
export function updateMemberLabel(params: Record<string, any>) {
return request.put(`member/label/${params.label_id}`, params, {showSuccessMessage: true})
}
/**
* 删除会员标签
* @param label_id
* @returns
*/
export function deleteMemberLabel(label_id: number) {
return request.delete(`member/label/${label_id}`, {showSuccessMessage: true})
}
/**
* 获取全部会员标签
*/
export function getMemberLabelAll() {
return request.get(`member/label/all`);
}
/**
* 编辑会员详情
* @param params
*/
export function editMemberDetail(params: Record<string, any>) {
return request.put(`member/member/modify/${params.member_id}/${params.field}`, params, {showSuccessMessage: true})
}
/***************************************************** 会员零钱 ****************************************************/
/***************************************************** 会员账户 ****************************************************/
/**
* 账户变动方式
* @param change_type
*/
export function getChangeTypeList(change_type: string) {
return request.get(`member/account/change_type/${change_type}`)
}
/**
* 会员积分流水
* @param params
* @returns
*/
export function getPointList(params: Record<string, any>) {
return request.get(`member/account/point`, {params})
}
/**
* 会员余额流水
* @param params
* @returns
*/
export function getBalanceList(params: Record<string, any>) {
return request.get(`member/account/balance`, {params})
}
/**
* 获取会员可提现余额列表
* @param params
* @returns
*/
export function getMoneyList(params: Record<string, any>) {
return request.get(`member/account/money`, {params})
}
/**
* 获取会员佣金列表
* @param params
* @returns
*/
export function getCommissionList(params: Record<string, any>) {
return request.get(`member/account/commission`, {params})
}
/**
* 会员积分调整
* @param params
* @returns
*/
export function adjustPoint(params: Record<string, any>) {
return request.post(`member/account/point`, params, {showSuccessMessage: true})
}
/**
* 会员余额调整
* @param params
* @returns
*/
export function adjustBalance(params: Record<string, any>) {
return request.post(`member/account/balance`, params, {showSuccessMessage: true})
}
/***************************************************** 会员相关设置 ****************************************************/
/**
* 获取登录设置
*/
export function getLoginConfig() {
return request.get(`member/config/login`)
}
/**
* 注册登录设置
* @param params
* @returns
*/
export function setLoginConfig(params: Record<string, any>) {
return request.post(`member/config/login`, params, {showSuccessMessage: true})
}
/**
* 获取会员设置
*/
export function getMemberConfig() {
return request.get(`member/config/member`)
}
/**
* 会员设置
* @param params
* @returns
*/
export function setMemberConfig(params: Record<string, any>) {
return request.post(`member/config/member`, params, {showSuccessMessage: true})
}
/**
* 获取会员转账方式
*/
export function getTransfertype() {
return request.get(`member/cash_out/transfertype`)
}
/**
* 佣金统计
* @param params
* @returns
*/
export function getCommissionSum(params: Record<string, any>) {
return request.get(`member/account/sum_commission`, {params})
}
/**
* 积分统计
* @param params
* @returns
*/
export function getPointSum(params: Record<string, any>) {
return request.get(`member/account/sum_point`, {params})
}
/**
* 余额统计
* @param params
* @returns
*/
export function getBalanceSum(params: Record<string, any>) {
return request.get(`member/account/sum_balance`, {params})
}
/**
* 余额类型
*/
export function getBalanceStatus() {
return request.get(`member/account/type`)
}
/**
* 获取余额变动类型
*/
export function getAccountType(params: Record<string, any>) {
return request.get(`member/account/change_type/${params.account_type}`)
}
/***************************************************** 会员提现 ****************************************************/
/**
* 获取提现设置
*/
export function getCashOutConfig() {
return request.get(`member/config/cash_out`)
}
/**
* 设置提现设置
* @param params
* @returns
*/
export function setCashOutConfig(params: Record<string, any>) {
return request.post(`member/config/cash_out`, params, {showSuccessMessage: true})
}
/**
* 获取会员提现列表
* @param params
* @returns
*/
export function getCashOutList(params: Record<string, any>) {
return request.get(`member/cash_out`, {params})
}
/**
* 会员提现详情
* @param id
*/
export function getCashOutDetail(id: number) {
return request.get(`member/cash_out/${id}`, {})
}
/**
* 会员提现审核
* @param params
*/
export function memberAudit(params: Record<string, any>) {
return request.put(`member/cash_out/audit/${params.id}/${params.action}`, params, {showSuccessMessage: true})
}
/**
* 会员提现转账
* @param params
*/
export function memberTransfer(params: Record<string, any>) {
return request.put(`member/cash_out/transfer/${params.id}`, params, {showSuccessMessage: true})
}
/**
* 会员状态变更
* @param params
*/
export function editMemberStatus(params: Record<string, any>) {
return request.put(`member/setstatus/${params.status}`, params, {showSuccessMessage: true})
}
/**
* 会员提现状态
*/
export function getCashOutStatusList() {
return request.get(`member/cash_out/status`)
}
/**
* 提现统计
* @returns
*/
export function getCashOutStat() {
return request.get(`member/cash_out/stat`)
}

67
admin/src/app/api/module.ts

@ -0,0 +1,67 @@
import request from '@/utils/request'
/**
* 获取授权信息
*/
export function getAuthinfo() {
return request.get('niucloud/authinfo', { showErrorMessage: false })
}
/**
* 设置 授权配置
*/
export function setAuthinfo(params: Record<string, any>) {
return request.post('niucloud/authinfo', params, {showSuccessMessage: true})
}
/**
* 获取 授权配置
*/
export function getAdminAuthinfo() {
return request.get('niucloud/admin/authinfo')
}
/**
* 获取授权插件列表
* @returns
*/
export function getModule() {
return request.get('niucloud/module')
}
/**
* 获取插件版本
* @param params
* @returns
*/
export function getModuleVersion() {
return request.get(`niucloud/module`)
}
/**
* 下载版本
* @param params
* @returns
*/
export function downloadVersion(params: Record<string, any>) {
return request.post(`addon/download/${params.addon}`, params, { showSuccessMessage: true })
}
/**
* 获取框架最新版本
* @param params
* @returns
*/
export function getFrameworkNewVersion() {
return request.get(`niucloud/framework/newversion`)
}
/**
* 获取框架更新记录
* @returns
*/
export function getFrameworkVersionList() {
return request.get(`niucloud/framework/version/list`)
}

81
admin/src/app/api/notice.ts

@ -0,0 +1,81 @@
import request from '@/utils/request'
/***************************************************** 消息管理 ****************************************************/
/**
* 消息列表
* @returns
*/
export function getNoticeList() {
return request.get('notice/notice')
}
/**
* 消息详情
* @param key
* @returns
*/
export function getNoticeInfo(key: string) {
return request.get(`notice/notice/${key}`)
}
/**
* 消息发送记录
* @param params
* @returns
*/
export function getNoticeLog(params: any) {
return request.get(`notice/log`, {params})
}
/**
* 消息启动与关闭
* @param params
* @returns
*/
export function editNoticeStatus(params: Record<string, any>) {
return request.post(`notice/notice/editstatus`, params, {showSuccessMessage: true})
}
/**
* 消息修改
* @param params
* @returns
*/
export function editNotice(params: Record<string, any>) {
return request.post(`notice/notice/edit`, params, {showSuccessMessage: true})
}
/**
* 短信配置列表
* @returns
*/
export function getSmsList() {
return request.get('notice/notice/sms')
}
/**
* 短信配置详情
* @param sms_type
* @returns
*/
export function getSmsInfo(sms_type: string) {
return request.get(`notice/notice/sms/${sms_type}`,)
}
/**
* 短信配置修改
* @param params
*/
export function editSms(params: Record<string, any>) {
return request.put(`notice/notice/sms/${params.sms_type}`, params, {showSuccessMessage: true})
}
/**
* 短信发送记录
* @param params
*/
export function getSmsLog(params: Record<string, any>) {
return request.get(`notice/sms/log`, params)
}

70
admin/src/app/api/order.ts

@ -0,0 +1,70 @@
import request from '@/utils/request'
/***************************************************** 充值订单 ****************************************************/
/**
* 获取充值订单列表
* @param params
* @returns
*/
export function getRechargeOrderList(params: Record<string, any>) {
return request.get(`order/recharge`, {params})
}
/**
* 获取充值订单统计
* @param params
* @returns
*/
export function getRechargeStat(params: Record<string, any>) {
return request.get(`order/recharge/stat`, {params})
}
/**
* 获取充值订单详情
* @param order_id
* @returns
*/
export function getRechargeOrderInfo(order_id: number) {
return request.get(`order/recharge/${order_id}`);
}
/**
* 获取充值订单状态列表
* @returns
*/
export function getRechargeOrderStatusList() {
return request.get(`order/recharge/status`)
}
/**
* 获取退款记录
* @returns
*/
export function getRechargeRefund(params: Record<string, any>) {
return request.get(`order/recharge/refund`, {params})
}
/**
* 获取退款状态
* @returns
*/
export function getRechargeRefundStatus() {
return request.get(`order/recharge/refund/status`)
}
/**
* 充值订单发起退款
* @returns
*/
export function rechargeRefund(id: number) {
return request.put(`order/recharge/refund/${id}`, {}, {showSuccessMessage: true});
}
/**
* 获取退款统计
* @returns
*/
export function getRechargeRefundStat() {
return request.get(`order/recharge/refund/stat`);
}

71
admin/src/app/api/pay.ts

@ -0,0 +1,71 @@
import request from '@/utils/request'
/***************************************************** 账单列表 **************************************************/
/**
* 获取账单列表
* @param params
* @returns
*/
export function getAccountList(params: Record<string, any>) {
return request.get(`pay/account`, {params})
}
/**
* 获取账单详情
* @param id
*/
export function getAccountInfo(id: number) {
return request.get(`pay/account/${id}`)
}
/**
* 获取账单统计
* @returns
*/
export function getAccountStat() {
return request.get(`pay/account/stat`)
}
/**
* 获取账单类型
* @returns
*/
export function getAccountType() {
return request.get(`pay/account/type`)
}
/***************************************************** 退款信息 **************************************************/
/**
* 退款列表
* @param params
* @returns
*/
export function getPayRefundPages(params: Record<string, any>) {
return request.get(`pay/refund`, {params})
}
/**
* 获取退款详情
* @param id
*/
export function getPayRefundInfo(refund_no: string) {
return request.get(`pay/refund/${refund_no}`)
}
/**
* 退款方式
* @param id
*/
export function getRefundType() {
return request.get(`pay/refund/type`)
}
/**
* 退款转账
* @param id
*/
export function getRefundTransfer(params: Record<string, any>) {
return request.post(`pay/refund/transfer`, params, {showSuccessMessage: true})
}

18
admin/src/app/api/personal.ts

@ -0,0 +1,18 @@
import request from '@/utils/request'
/**
* 获取支付设置
* @returns
*/
export function getUserInfo() {
return request.get(`auth/get`)
}
/**
* 配置支付
* @returns
*/
export function setUserInfo(params: Record<string, any>) {
return request.put(`auth/edit`, params, {showSuccessMessage: true});
}

252
admin/src/app/api/site.ts

@ -0,0 +1,252 @@
import request from '@/utils/request'
//包含站点管理,站点用户管理,站点操作日志
/***************************************************** 站点管理 ****************************************************/
/**
* 获取站点列表
* @param params
* @returns
*/
export function getSiteList(params: Record<string, any>) {
return request.get(`site/site`, { params })
}
/**
* 获取站点详情
* @param site_id
*/
export function getSiteInfo(site_id: number) {
return request.get(`site/site/${site_id}`);
}
/**
* 添加站点
* @param params
* @returns
*/
export function addSite(params: Record<string, any>) {
return request.post('site/site', params, { showSuccessMessage: true })
}
/**
* 更新站点
* @param params
*/
export function editSite(params: Record<string, any>) {
return request.put(`site/site/${params.site_id}`, params, { showSuccessMessage: true })
}
/**
* 删除站点
* @param siteId
*/
export function deleteSite(siteId: number) {
return request.delete(`site/site/${siteId}`)
}
/**
* 关闭站点
* @param params
*/
export function closeSite(params: Record<string, any>) {
return request.put(`site/closesite/${params.site_id}`, params, { showSuccessMessage: true })
}
/**
* 打开站点
* @param params
*/
export function openSite(params: Record<string, any>) {
return request.put(`site/opensite/${params.site_id}`, params, { showSuccessMessage: true })
}
/**
* 获取全部站点状态
*/
export function getStatusList() {
return request.get(`site/statuslist`)
}
/***************************************************** 站点分组管理 ****************************************************/
/**
* 获取站点分组列表
* @param params
* @returns
*/
export function getSiteGroupList(params: Record<string, any>) {
return request.get(`site/group`, { params })
}
/**
* 获取站点分组详情
* @param site_id
*/
export function getSiteGroupInfo(groupId: number) {
return request.get(`site/group/${groupId}`);
}
/**
* 添加站点分组
* @param params
* @returns
*/
export function addSiteGroup(params: Record<string, any>) {
return request.post('site/group', params, { showSuccessMessage: true })
}
/**
* 更新站点分组
* @param params
*/
export function editSiteGroup(params: Record<string, any>) {
return request.put(`site/group/${params.group_id}`, params, { showSuccessMessage: true })
}
/**
* 删除站点分组
* @param group_id
*/
export function deleteSiteGroup(group_id: number) {
return request.delete(`site/group/${group_id}`, { showSuccessMessage: true });
}
/**
* 获取全部站点分组
* @param params
* @returns
*/
export function getSiteGroupAll(params: Record<string, any> = {}) {
return request.get(`site/group/all`)
}
/***************************************************** 当前站点用户 *************************************************/
/**
* 获取站点用户列表
* @param params
* @returns
*/
export function getUserList(params: Record<string, any>) {
return request.get(`site/user`, { params })
}
/**
* 获取站点用户详情
* @param uid
*/
export function getUserInfo(uid: number) {
return request.get(`site/user/${uid}`);
}
/**
* 添加用户
* @param params
* @returns
*/
export function addUser(params: Record<string, any>) {
return request.post('site/user', params, { showSuccessMessage: true })
}
/**
* 编辑用户
* @param params
*/
export function editUser(params: Record<string, any>) {
return request.put(`site/user/${params.uid}`, params, { showSuccessMessage: true })
}
/**
* 删除用户
* @param uid
* @returns
*/
export function deleteUser(uid: number) {
return request.delete(`site/user/${uid}`, { showSuccessMessage: true })
}
/**
* 锁定用户
* @param uid
* @returns
*/
export function lockUser(uid: number) {
return request.put(`site/user/lock/${uid}`)
}
/**
* 解锁用户
* @param uid
* @returns
*/
export function unlockUser(uid: number) {
return request.put(`site/user/unlock/${uid}`)
}
/***************************************************** 操作日志 **************************************************/
/**
* 获取操作日志列表
* @param params
* @returns
*/
export function getLogList(params: Record<string, any>) {
return request.get(`site/log`, { params })
}
/**
* 获取操作日志详情
* @param id
*/
export function getLogInfo(id: number) {
return request.get(`site/log/${id}`)
}
/***************************************************** 账单列表 **************************************************/
/**
* 获取账单列表
* @param params
* @returns
*/
export function getAccountList(params: Record<string, any>) {
return request.get(`site/account`, { params })
}
/**
* 获取账单详情
* @param id
*/
export function getAccountInfo(id: number) {
return request.get(`site/account/${id}`)
}
/**
* 获取账单统计
* @returns
*/
export function getAccountStat() {
return request.get(`site/account/stat`)
}
/**
* 获取账单类型
* @returns
*/
export function getAccountType() {
return request.get(`site/account/type`)
}
/**
* 获取站点应用
* @returns
*/
export function getSiteAddons() {
return request.get('site/addons')
}

17
admin/src/app/api/stat.ts

@ -0,0 +1,17 @@
import request from '@/utils/request'
/***************************************************** 统计信息 **************************************************/
/**
* 获取统计信息
*/
export function getStatInfo() {
return request.get(`stat/index`)
}
/**
* 获取站点统计信息
*/
export function getSiteStatInfo() {
return request.get(`stat/siteindex`)
}

702
admin/src/app/api/sys.ts

@ -0,0 +1,702 @@
import request from '@/utils/request'
/***************************************************** 系统整体信息 *************************************************/
/**
* 系统信息
* @returns
*/
export function getInfo() {
return request.get('sys/role')
}
/**
* 系统信息
* @returns
*/
export function getUrl() {
return request.get('sys/url')
}
/***************************************************** 用户组 ****************************************************/
/**
* 用户组列表
* @returns
*/
export function getRoleList(params: Record<string, any>) {
return request.get('sys/role', { params })
}
/**
* 用户组详情
* @param roleId
*/
export function getRoleInfo(roleId: number) {
return request.get(`sys/role/${roleId}`)
}
/**
* 添加用户组
* @param params
* @returns
*/
export function addRole(params: Record<string, any>) {
return request.post(`sys/role`, params, { showSuccessMessage: true })
}
/**
* 编辑用户组
* @param params
*/
export function editRole(params: Record<string, any>) {
return request.put(`sys/role/${params.role_id}`, params, { showSuccessMessage: true })
}
/**
* 删除用户组
* @param roleId
*/
export function deleteRole(roleId: number) {
return request.delete(`sys/role/${roleId}`, { showSuccessMessage: true })
}
/**
* 全部分组
* @returns
*/
export function allRole() {
return request.get('sys/role/all')
}
/***************************************************** 全部菜单 ****************************************************/
/**
* 获取全部菜单
* @returns
*/
export function getMenus(type: string) {
return request.get(`sys/menu/${type}`)
}
/**
* 获取菜单信息
* @param menu_key
*/
export function getMenuInfo(app_type: string, menu_key: string) {
return request.get(`sys/menu/${app_type}/info/${menu_key}`);
}
/**
* 添加菜单
* @param params
* @returns
*/
export function addMenu(params: Record<string, any>) {
return request.post('sys/menu', params, { showSuccessMessage: true })
}
/**
* 更新菜单
* @param params
*/
export function editMenu(params: Record<string, any>) {
return request.put(`sys/menu/${params.app_type}/${params.menu_key}`, params, { showSuccessMessage: true })
}
/**
* 删除菜单
* @param menu_key
*/
export function deleteMenu(app_type: string, menu_key: string) {
return request.delete(`sys/menu/${app_type}/${menu_key}`, { showSuccessMessage: true })
}
/**
* 获取系统菜单
*
*/
export function getSystemMenu() {
return request.get(`sys/menu/system_menu`)
}
/**
* 获取应用菜单
*
*/
export function getAddonMenu(key: any) {
return request.get(`sys/menu/addon_menu/${key}`)
}
/**
* 获取类型为目录的菜单
* @param key
*/
export function getMenuByTypeDir(key: any = 'system') {
return request.get(`sys/menu/dir/${key}`)
}
/***************************************************** 站点菜单 ****************************************************/
/**
* 获取站点菜单
* @returns
*/
export function getSiteMenus() {
return request.get(`site/site/menu`)
}
/***************************************************** 设置 ****************************************************/
/**
* 获取网站设置
* @returns
*/
export function getWebsite() {
return request.get('sys/config/website')
}
/**
* 获取网站设置
* @returns
*/
export function getWebConfig() {
return request.get('sys/web/website')
}
/**
* 获取网站设置
* @returns
*/
export function getWebCopyright() {
return request.get('sys/web/copyright')
}
/**
* 更新网站设置
* @param params
* @returns
*/
export function setWebsite(params: Record<string, any>) {
return request.put(`sys/config/website`, params, { showSuccessMessage: true })
}
/**
* 获取版权设置
* @returns
*/
export function getCopyright() {
return request.get('sys/config/copyright')
}
/**
* 获服务信息
* @returns
*/
export function getService() {
return request.get('sys/config/service')
}
/**
* 更新版权设置
* @param params
* @returns
*/
export function setCopyright(params: Record<string, any>) {
return request.put(`sys/config/copyright`, params, { showSuccessMessage: true })
}
/**
* 获取附件组列表
* @param params
* @returns
*/
export function getAttachmentCategoryList(params: Record<string, any>) {
return request.get(`sys/attachment/category`, { params })
}
/**
* 添加分类
* @param params
*/
export function addAttachmentCategory(params: Record<string, any>) {
return request.post(`sys/attachment/category`, params, { showSuccessMessage: true })
}
/**
* 编辑分类
* @param params
* @returns
*/
export function editAttachmentCategory(params: Record<string, any>) {
return request.put(`sys/attachment/category/${params.id}`, params, { showSuccessMessage: true })
}
/**
* 删除分类
* @param id
* @returns
*/
export function deleteAttachmentCategory(id: number) {
return request.delete(`sys/attachment/category/${id}`, { showSuccessMessage: true })
}
/**
* 获取附件列表
* @param params
* @returns
*/
export function getAttachmentList(params: Record<string, any>) {
return request.get(`sys/attachment`, { params })
}
/**
* 删除附件
* @param params
* @returns
*/
export function deleteAttachment(params: Record<string, any>) {
return request.delete(`sys/attachment/del`, { data: params, showSuccessMessage: true })
}
/**
* 移动附件
* @param params
* @returns
*/
export function moveAttachment(params: Record<string, any>) {
return request.put(`sys/attachment/batchmove`, params)
}
/**
* 获取menu菜单
*/
export function getAuthMenu() {
return request.get(`auth/site/showmenu`)
}
/**
* 获取快捷菜单
*/
export function getShortcutMenu() {
return request.get(`sys/config/shortcut_menu`)
}
/**
* 添加快捷菜单
*/
export function setShortcutMenu(params: Record<string, any>) {
return request.put(`sys/config/shortcut_menu`, params, { showSuccessMessage: true })
}
/**
* 获取图标库分类列表
* @param params
* @returns
*/
export function getIconCategoryList(params: Record<string, any>) {
return request.get(`sys/attachment/icon_category`, { params })
}
/**
* 获取图标库列表
* @param params
* @returns
*/
export function getIconList(params: Record<string, any>) {
return request.get(`sys/attachment/icon`, { params })
}
/**
* 获取evn
* @param params
* @returns
*/
export function getEnv() {
return request.get(`sys/env`)
}
/***************************************************** 地址管理 ****************************************************/
/**
* 获取下级地址列表
* @param pid
*/
export function getAreaListByPid(pid: number = 0) {
return request.get(`sys/area/list_by_pid/${pid}`)
}
/**
* 获取地址树列表
* @param level
*/
export function getAreatree(level: number = 1) {
return request.get(`sys/area/tree/${level}`)
}
/**
* 获取地址信息
*/
export function getAddressInfo(params: any) {
return request.get(`sys/area/get_info`, { params })
}
/**
* 获取地址信息
*/
export function getContraryAddress(params: any) {
return request.get(`sys/area/contrary`, { params })
}
/**
* 获取地址
* @param code
*/
export function getAreaByCode(code: number | string) {
return request.get(`sys/area/code/${code}`)
}
/***************************************************** 存储设置 ****************************************************/
/**
* 获取存储配置列表
*/
export function getStorageList() {
return request.get(`sys/storage`)
}
/**
* 获取存储详情
* @param type
*/
export function getStorageInfo(type: string) {
return request.get(`sys/storage/${type}`)
}
/**
* 修改存储
* @param params
* @returns
*/
export function editStorage(params: Record<string, any>) {
return request.put(`sys/storage/${params.storage_type}`, params, { showSuccessMessage: true })
}
/***************************************************** 支付设置 ****************************************************/
/**
* 获取支付设置
* @returns
*/
export function getPayConfig(type: string) {
return request.get(`pay/config/${type}`)
}
/**
* 配置支付
* @returns
*/
export function setPayConfig(params: Record<string, any>) {
return request.put(`pay/config/${params.type}`, params, { showSuccessMessage: true });
}
/**
* 获取支付列表
* @returns
*/
export function getPayList() {
return request.get(`pay/lists`)
}
/***************************************************** 打款设置 ****************************************************/
/**
* 获取打款设置配置
* @param channel
*/
export function getTransferInfo(channel) {
return request.get(`pay/channel/lists/${channel}`)
}
/**
* 设置打款配置
* @param params
* @returns
*/
export function setTransferInfo(params: Record<string, any>) {
return request.post(`pay/channel/set/transfer`, params)
}
/***************************************************** 定时任务 ****************************************************/
/**
* 获取任务列表
* @returns
*/
export function getCronList(params: any) {
return request.get(`sys/schedule/list`, { params })
}
/**
* 任务详情
* @returns
*/
export function getCronInfo(id: string) {
return request.get(`sys/cron/${id}`);
}
/**
* 任务模版
* @returns
*/
export function getCronTemplate() {
return request.get(`sys/schedule/template`)
}
/**
* 任务间隔
* @returns
*/
export function getCronDateType() {
return request.get(`sys/schedule/datetype`)
}
/**
* 获取星期
* @returns
*/
export function getWeek() {
return request.get(`sys/date/week`)
}
/**
* 添加计划任务
* @returns
*/
export function addCron(params: Record<string, any>) {
return request.post(`sys/schedule`, params, { showSuccessMessage: true })
}
/**
* 编辑任务
* @returns
*/
export function editCron(params: Record<string, any>) {
return request.put(`sys/schedule/${params.id}`, params, { showSuccessMessage: true })
}
/**
* 删除任务
* @returns
*/
export function deleteCron(id: string) {
return request.delete(`sys/schedule/${id}`, { showSuccessMessage: true })
}
/***************************************************** 协议管理 ****************************************************/
/**
* 获取协议列表
* @returns
*/
export function getAgreementList() {
return request.get(`sys/agreement`)
}
/**
* 协议详情
* @returns
*/
export function getAgreementInfo(key: string) {
return request.get(`sys/agreement/${key}`);
}
/**
* 更新协议
* @returns
*/
export function editAgreement(params: Record<string, any>) {
return request.put(`sys/agreement/${params.key}`, params, { showSuccessMessage: true })
}
/**
* 协议详情
* @returns
*/
export function getChannelType() {
return request.get(`sys/channel`);
}
/**
* 获取渠道域名
* @returns
*/
export function getSceneDomain() {
return request.get(`sys/scene_domain`);
}
/***************************************************** 登录注册配置 ****************************************************/
/**
* 管理端登录注册配置
*/
export function getConfigLogin() {
return request.get(`sys/config/login`)
}
/**
* 设置管理端登录注册配置
* @param params
* @returns
*/
export function setConfigLogin(params: Record<string, any>) {
return request.put(`sys/config/login`, params, { showSuccessMessage: true })
}
/**
* 获取支付设置
*/
export function getPayConfigList() {
return request.get(`pay/channel/lists`)
}
/**
* 设置支付配置
*/
export function setPatConfig(params: Record<string, any>) {
return request.post(`pay/channel/set/all`, params, { showSuccessMessage: true })
}
/***************************************************** 刷新菜单 ****************************************************/
/**
* 刷新菜单
*/
export function menuRefresh(params: Record<string, any>) {
return request.post(`sys/menu/refresh`, {}, { showSuccessMessage: true })
}
/**
* 清理数据字段缓存
*/
export function clearSchemaCache(params: Record<string, any>) {
return request.post(`sys/schema/clear`, {}, { showSuccessMessage: true })
}
/***************************************************** 获取应用 ****************************************************/
/**
* 获取应用
*/
export function getAppMange() {
return request.get(`sys/applist`)
}
/***************************************************** 地图设置 ****************************************************/
/**
* 设置地图key
*/
export function setMap(params: Record<string, any>) {
return request.put(`sys/config/map`, params, { showSuccessMessage: true })
}
/**
* 获取地图配置
*/
export function getMap() {
return request.get(`sys/config/map`)
}
/***************************************************** 首页 ****************************************************/
/**
* 获取首页列表
*/
export function getIndexList() {
return request.get(`sys/config/site_index`)
}
/**
* 设置首页模版
*/
export function setIndexList(params: Record<string, any>) {
return request.put(`sys/config/site_index`, params, { showSuccessMessage: true })
}
/**
* 获取布局
* @returns
*/
export function getLayouts() {
return request.get('sys/layout')
}
/**
* 设置布局
* @returns
*/
export function setLayout(key: string) {
return request.put('sys/layout', { key }, { showSuccessMessage: true })
}
/**
* 获取支付待审核记录
*/
export function getPayAuditList(params: Record<string, any>) {
return request.get('pay/audit', { params })
}
/**
* 支付审核通过
* @returns
*/
export function payAuditPass(outTradeNo: string) {
return request.put(`pay/pass/${outTradeNo}`, {}, { showSuccessMessage: true })
}
/**
* 支付审核拒绝
* @returns
*/
export function payAuditRefuse(params: Record<string, any>) {
return request.put(`pay/refuse/${params.out_trade_no}`, params, { showSuccessMessage: true })
}
/**
* 获取支付单据详情
*/
export function getPayDetail(id: number) {
return request.get(`pay/detail/${id}`)
}
/**
* 获取应用列表
*/
export function getAddonList() {
return request.get(`app/getAddonList`)
}
/**
* 获取手机端首页列表
*/
export function getWapIndexList(params: Record<string, any>) {
return request.get('sys/config/wap_index', { params })
}
/**
* 获取开发者key
* @returns
*/
export function getDeveloperToken() {
return request.get('sys/config/developer_token')
}
/**
* 设置开发者key
* @param params
* @returns
*/
export function setDeveloperToken(params: Record<string, any>) {
return request.put(`sys/config/developer_token`, params, { showSuccessMessage: true })
}

184
admin/src/app/api/tools.ts

@ -0,0 +1,184 @@
import request from '@/utils/request'
/***************************************************** 插件开发 ****************************************************/
/**
* 获取插件列表
* @returns
*/
export function getAddonDevelop(params: Record<string, any>) {
return request.get(`addon_develop`, {params});
}
/**
* 获取插件类型配置
* @returns
*/
export function getAddontype() {
return request.get(`addontype`);
}
/**
* 获取插件详情
* @returns
*/
export function getAddonDevelopInfo(key: any) {
return request.get(`addon_develop/${key}`)
}
/**
* 获取插件key是否存在
* @returns
*/
export function getAddonDevelopCheck(key: any) {
return request.get(`addon_develop/check/${key}`)
}
/**
* 添加插件
* @param key
* @param params
* @returns
*/
export function addAddonDevelop(key: any, params: Record<string, any>) {
return request.post(`addon_develop/${key}`, params)
}
/**
* 编辑插件
* @param key
* @param params
* @returns
*/
export function editAddonDevelop(key: any, params: Record<string, any>) {
return request.put(`addon_develop/${key}`, params)
}
/**
* 删除插件
* @param key
* @returns
*/
export function deleteAddonDevelop(key: any) {
return request.delete(`addon_develop/${key}`, {showSuccessMessage: true})
}
/**
* 打包插件
* @returns
*/
export function addonDevelopBuild(key: any) {
return request.post(`addon_develop/build/${key}`)
}
/**
* 下载插件
* @returns
*/
export function addonDevelopDownload(key: any) {
return request.post(`addon_develop/download/${key}`, {})
}
/***************************************************** 代码生成 ****************************************************/
/**
* 获取代码生成列表
* @param params
* @returns
*/
export function getGenerateTableList(params: Record<string, any>) {
return request.get(`generator/generator`, {params})
}
/**
* 获取代码生成详情
* @param id 代码生成id
* @returns
*/
export function getGenerateTableInfo(id: number) {
return request.get(`generator/generator/${id}`);
}
/**
* 添加代码生成
* @param params
* @returns
*/
export function addGenerateTable(params: Record<string, any>) {
return request.post('generator/generator', params, {showSuccessMessage: true})
}
/**
* 编辑代码生成
* @param params
*/
export function editGenerateTable(params: Record<string, any>) {
return request.put(`generator/generator/${params.id}`, params, {showSuccessMessage: true})
}
/**
* 删除代码生成
* @param id
* @returns
*/
export function deleteGenerateTable(id: number) {
return request.delete(`generator/generator/${id}`, {showSuccessMessage: true})
}
/**
* 代码生成
* @param params
* @returns
*/
export function generateCreate(params: Record<string, any>) {
return request.post(`generator/download`, params)
}
/**
* 代码生成预览
* @param id
* @returns
*/
export function generatePreview(id: number) {
return request.get(`generator/preview/${id}`)
}
/**
* 数据表
*/
export function generateTable() {
return request.get(`generator/table`)
}
/**
* 获取服务器环境配置
*/
export function getSystem() {
return request.get(`sys/system`)
}
/**
* 获取全部模型
*/
export function getGeneratorAllModel(params: any) {
return request.get(`generator/all_model`, {params})
}
/**
* 获取 表字段
*/
export function getGeneratorTableColumn(params: any) {
return request.get(`generator/table_column`, {params})
}
/**
* 同步校验
*/
export function generatorCheckFile(params: Record<string, any>) {
return request.get(`generator/check_file`, {params})
}
/**
* 根据模型获取表字段
*/
export function getGeneratorModelTableColumn(params: any) {
return request.get(`generator/model_table_column`, {params})
}

47
admin/src/app/api/upgrade.ts

@ -0,0 +1,47 @@
import request from '@/utils/request'
/**
* 获取更新内容
* @param addon
*/
export function getUpgradeContent(addon: string = '') {
return request.get(addon ? `upgrade/${addon}` : 'upgrade')
}
/**
* 获取升级任务
* @param addon
*/
export function getUpgradeTask() {
return request.get('upgrade/task')
}
/**
* 升级
* @param addon
*/
export function upgradeAddon(addon: string = '') {
return request.post(addon ? `upgrade/${addon}` : 'upgrade')
}
/**
* 执行升级
*/
export function executeUpgrade() {
return request.post('upgrade/execute', {}, { timeout: 0 })
}
/**
* 升级前检测
*/
export function preUpgradeCheck(addon: string = '') {
return request.get(addon ? `upgrade/check/${addon}` : 'upgrade/check')
}
/**
* 清除
*/
export function clearUpgradeTask() {
return request.post('upgrade/clear')
}

58
admin/src/app/api/user.ts

@ -0,0 +1,58 @@
import request from '@/utils/request'
//当前接口用户指系统整体用户管理,站内用户添加,编辑,详情,操作日志,请查看站点内部相关接口
/***************************************************** 用户 ****************************************************/
/**
* 获取用户列表
* @param params
* @returns
*/
export function getUserList(params: Record<string, any>) {
return request.get(`user/user`, { params })
}
/**
* 获取用户详情
* @param uid 用户uid
* @returns
*/
export function getUserInfo(uid: number) {
return request.get(`user/user/${uid}`);
}
/**
* 添加用户
* @param params
* @returns
*/
export function addUser(params: Record<string, any>) {
return request.post('user/user', params, { showSuccessMessage: true })
}
/**
* 更新用户
* @param params
*/
export function editUser(params: Record<string, any>) {
return request.put(`user/user/${params.uid}`, params, { showSuccessMessage: true })
}
/**
* 获取所有用户列表
* @param params
* @returns
*/
export function getAllUserList(params: Record<string, any>) {
return request.get(`user/user_all`, { params })
}
/**
* 查询用户名是否存在
* @param username
* @returns
*/
export function checkUsernameIsExist(username: string) {
return request.get(`user/isexist`, { params: { username } })
}

125
admin/src/app/api/weapp.ts

@ -0,0 +1,125 @@
import request from '@/utils/request'
/**
* 获取微信小程序配置
* @returns
*/
export function getWeappConfig() {
return request.get('weapp/config')
}
/**
* 编辑微信小程序配置
* @param params
* @returns
*/
export function setWeappConfig(params: Record<string, any>) {
return request.put('weapp/config', params, { showSuccessMessage: true })
}
/**
* 获取订阅消息列表
* @returns
*/
export function getTemplateList() {
return request.get('weapp/template')
}
/**
* 获取同步
* @param params
* @returns
*/
export function getBatchAcquisition(params: Record<string, any>) {
return request.put('weapp/template/sync', params, { showSuccessMessage: true })
}
/**
* 添加微信小程序版本
* @param params
* @returns
*/
export function setWeappVersion(params: Record<string, any>) {
return request.post('weapp/version', params, { showSuccessMessage: true })
}
/**
* 微信小程序预览码
* @returns
*/
export function getWeappPreview() {
return request.get('weapp/preview')
}
/**
* 微信小程序版本列表
* @param params
* @returns
*/
export function getWeappVersionList(params: Record<string, any>) {
return request.get('weapp/version', { params })
}
/**
* 获取微信小程序上传日志
* @param key
* @returns
*/
export function getWeappUploadLog(key: string) {
return request.get(`weapp/upload/${key}`)
}
/***************************************************** 管理端 ****************************************************/
/**
* 上传文件
* @param params
* @returns
*/
export function uploadVersion(params: Record<string, any>) {
return request.put('applet/upload', params, { showSuccessMessage: true })
}
/**
* 添加版本
* @param params
* @returns
*/
export function addVersion(params: Record<string, any>) {
return request.post('applet/version', params, { showSuccessMessage: true })
}
/**
* 版本列表
* @param params
* @returns
*/
export function getVersionList(params: Record<string, any>) {
return request.get('applet/version', { params })
}
/**
* 版本详情
* @param id
* @returns
*/
export function getVersionInfo(id: string) {
return request.get(`applet/version/${id}`)
}
/**
* 编辑版本
* @param params
* @returns
*/
export function editVersion(params: Record<string, any>) {
return request.put(`applet/version/${params.id}`, params, { showSuccessMessage: true })
}
/**
* 版本删除
* @param id
* @returns
*/
export function deleteVersion(id: string) {
return request.delete(`applet/version/${id}`)
}

64
admin/src/app/api/wechat.ts

@ -0,0 +1,64 @@
import request from '@/utils/request'
/**
* 获取微信配置
* @returns
*/
export function getWechatConfig() {
return request.get('wechat/config')
}
/**
* 微信配置所需的静态信息
*/
export function getWechatStatic() {
return request.get('wechat/static');
}
/**
* 编辑微信配置
* @param params
* @returns
*/
export function editWechatConfig(params: Record<string, any>) {
return request.put('wechat/config', params, {showSuccessMessage: true})
}
/**
* 获取微信菜单
* @returns
*/
export function getWechatMenu() {
return request.get('wechat/menu')
}
/**
* 编辑微信菜单
* @param params
* @returns
*/
export function editWechatMenu(params: Record<string, any>) {
return request.put('wechat/menu', params, {showSuccessMessage: true})
}
/**
* 获取消息模板列表
* @returns
*/
export function getTemplateList() {
return request.get('wechat/template')
}
/**
* 获取同步
* @param params
* @returns
*/
export function getBatchAcquisition(params: Record<string, any>) {
return request.put('wechat/template/sync', params, {showSuccessMessage: true})
}

BIN
admin/src/app/assets/images/SaaS.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

BIN
admin/src/app/assets/images/app_default.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
admin/src/app/assets/images/app_store/app_store_default.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

BIN
admin/src/app/assets/images/app_store/local_icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

BIN
admin/src/app/assets/images/app_store/local_icon_select.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

BIN
admin/src/app/assets/images/app_store/market_icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
admin/src/app/assets/images/app_store/market_icon_select.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
admin/src/app/assets/images/app_store/switch_icon_1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

BIN
admin/src/app/assets/images/app_store/switch_icon_2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

BIN
admin/src/app/assets/images/back_login.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
admin/src/app/assets/images/category_default.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
admin/src/app/assets/images/channel/preview.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 KiB

BIN
admin/src/app/assets/images/default_headimg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
admin/src/app/assets/images/diy/notice/style_01.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
admin/src/app/assets/images/diy/text/style1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
admin/src/app/assets/images/diy/text/style2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
admin/src/app/assets/images/diy_preview_head.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
admin/src/app/assets/images/empty.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

BIN
admin/src/app/assets/images/error.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
admin/src/app/assets/images/gov_icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
admin/src/app/assets/images/icon-addon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
admin/src/app/assets/images/icon_folder.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

BIN
admin/src/app/assets/images/icon_preview.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

BIN
admin/src/app/assets/images/index/add_menu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 B

BIN
admin/src/app/assets/images/index/administrator.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
admin/src/app/assets/images/index/app.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
admin/src/app/assets/images/index/app1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
admin/src/app/assets/images/index/app_default.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
admin/src/app/assets/images/index/apply_empty.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
admin/src/app/assets/images/index/article.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
admin/src/app/assets/images/index/article_list.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
admin/src/app/assets/images/index/auth.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
admin/src/app/assets/images/index/auth1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
admin/src/app/assets/images/index/balance.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

BIN
admin/src/app/assets/images/index/del_model.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save