Browse Source

feat(zhjw): 文章管理增加创建时间和更新时间筛选功能

- 在文章管理列表中添加创建时间和更新时间的筛选条件- 在后端增加相应的搜索器方法
- 更新前端界面,增加时间筛选的表单元素
- 优化数据模型,使用软删除标记字段
master
liutong 1 year ago
parent
commit
98abe41e8c
  1. 8
      .gitignore
  2. 2
      admin/.env.development
  3. 2
      admin/auto-imports.d.ts
  4. 1
      admin/components.d.ts
  5. 6
      admin/src/addon/zhjw/api/articles.ts
  6. 62
      admin/src/addon/zhjw/api/contracts.ts
  7. 56
      admin/src/addon/zhjw/api/orders.ts
  8. 58
      admin/src/addon/zhjw/api/students.ts
  9. 62
      admin/src/addon/zhjw/api/users.ts
  10. 7
      admin/src/addon/zhjw/lang/zh-cn/articles.articles.json
  11. 2
      admin/src/addon/zhjw/lang/zh-cn/articles.articles_edit.json
  12. 21
      admin/src/addon/zhjw/lang/zh-cn/contracts.contracts.json
  13. 19
      admin/src/addon/zhjw/lang/zh-cn/contracts.contracts_edit.json
  14. 26
      admin/src/addon/zhjw/lang/zh-cn/orders.orders.json
  15. 19
      admin/src/addon/zhjw/lang/zh-cn/orders.orders_edit.json
  16. 25
      admin/src/addon/zhjw/lang/zh-cn/students.students.json
  17. 19
      admin/src/addon/zhjw/lang/zh-cn/students.students_edit.json
  18. 88
      admin/src/addon/zhjw/lang/zh-cn/users.users.json
  19. 87
      admin/src/addon/zhjw/lang/zh-cn/users.users_edit.json
  20. 43
      admin/src/addon/zhjw/views/articles/articles.vue
  21. 31
      admin/src/addon/zhjw/views/articles/articles_edit.vue
  22. 244
      admin/src/addon/zhjw/views/contracts/contracts.vue
  23. 243
      admin/src/addon/zhjw/views/contracts/contracts_edit.vue
  24. 323
      admin/src/addon/zhjw/views/orders/orders.vue
  25. 279
      admin/src/addon/zhjw/views/orders/orders_edit.vue
  26. 249
      admin/src/addon/zhjw/views/students/students.vue
  27. 226
      admin/src/addon/zhjw/views/students/students_edit.vue
  28. 615
      admin/src/addon/zhjw/views/users/components/users-edit.vue
  29. 481
      admin/src/addon/zhjw/views/users/users.vue
  30. 612
      admin/src/addon/zhjw/views/users/users_edit.vue
  31. 2
      niucloud/.env
  32. 6
      niucloud/addon/zhjw/admin/api/articles.ts
  33. 62
      niucloud/addon/zhjw/admin/api/contracts.ts
  34. 56
      niucloud/addon/zhjw/admin/api/orders.ts
  35. 58
      niucloud/addon/zhjw/admin/api/students.ts
  36. 62
      niucloud/addon/zhjw/admin/api/users.ts
  37. 7
      niucloud/addon/zhjw/admin/lang/zh-cn/articles.articles.json
  38. 2
      niucloud/addon/zhjw/admin/lang/zh-cn/articles.articles_edit.json
  39. 21
      niucloud/addon/zhjw/admin/lang/zh-cn/contracts.contracts.json
  40. 19
      niucloud/addon/zhjw/admin/lang/zh-cn/contracts.contracts_edit.json
  41. 26
      niucloud/addon/zhjw/admin/lang/zh-cn/orders.orders.json
  42. 19
      niucloud/addon/zhjw/admin/lang/zh-cn/orders.orders_edit.json
  43. 25
      niucloud/addon/zhjw/admin/lang/zh-cn/students.students.json
  44. 19
      niucloud/addon/zhjw/admin/lang/zh-cn/students.students_edit.json
  45. 88
      niucloud/addon/zhjw/admin/lang/zh-cn/users.users.json
  46. 87
      niucloud/addon/zhjw/admin/lang/zh-cn/users.users_edit.json
  47. 43
      niucloud/addon/zhjw/admin/views/articles/articles.vue
  48. 31
      niucloud/addon/zhjw/admin/views/articles/articles_edit.vue
  49. 244
      niucloud/addon/zhjw/admin/views/contracts/contracts.vue
  50. 243
      niucloud/addon/zhjw/admin/views/contracts/contracts_edit.vue
  51. 323
      niucloud/addon/zhjw/admin/views/orders/orders.vue
  52. 279
      niucloud/addon/zhjw/admin/views/orders/orders_edit.vue
  53. 249
      niucloud/addon/zhjw/admin/views/students/students.vue
  54. 226
      niucloud/addon/zhjw/admin/views/students/students_edit.vue
  55. 615
      niucloud/addon/zhjw/admin/views/users/components/users-edit.vue
  56. 481
      niucloud/addon/zhjw/admin/views/users/users.vue
  57. 612
      niucloud/addon/zhjw/admin/views/users/users_edit.vue
  58. 5
      niucloud/addon/zhjw/app/adminapi/controller/articles/Articles.php
  59. 106
      niucloud/addon/zhjw/app/adminapi/controller/contracts/Contracts.php
  60. 112
      niucloud/addon/zhjw/app/adminapi/controller/orders/Orders.php
  61. 108
      niucloud/addon/zhjw/app/adminapi/controller/students/Students.php
  62. 205
      niucloud/addon/zhjw/app/adminapi/controller/users/Users.php
  63. 111
      niucloud/addon/zhjw/app/adminapi/route/route.php
  64. 52
      niucloud/addon/zhjw/app/model/articles/Articles.php
  65. 154
      niucloud/addon/zhjw/app/model/contracts/Contracts.php
  66. 184
      niucloud/addon/zhjw/app/model/orders/Orders.php
  67. 178
      niucloud/addon/zhjw/app/model/students/Students.php
  68. 520
      niucloud/addon/zhjw/app/model/users/Users.php
  69. 8
      niucloud/addon/zhjw/app/service/admin/articles/ArticlesService.php
  70. 105
      niucloud/addon/zhjw/app/service/admin/contracts/ContractsService.php
  71. 112
      niucloud/addon/zhjw/app/service/admin/orders/OrdersService.php
  72. 105
      niucloud/addon/zhjw/app/service/admin/students/StudentsService.php
  73. 104
      niucloud/addon/zhjw/app/service/admin/users/UsersService.php
  74. 2
      niucloud/addon/zhjw/app/validate/articles/Articles.php
  75. 37
      niucloud/addon/zhjw/app/validate/contracts/Contracts.php
  76. 46
      niucloud/addon/zhjw/app/validate/orders/Orders.php
  77. 43
      niucloud/addon/zhjw/app/validate/students/Students.php
  78. 49
      niucloud/addon/zhjw/app/validate/users/Users.php
  79. 2
      niucloud/app/service/admin/sys/MenuService.php
  80. 4
      niucloud/runtime/cache/00/796846cef72c1934f657158416effa.php
  81. 4
      niucloud/runtime/cache/07/4bfa60510f475862a98e416426f451.php
  82. 4
      niucloud/runtime/cache/08/cd218d3b0adb213bef402dcf69ffe7.php
  83. 4
      niucloud/runtime/cache/09/f3d0b8f0a6d3610ef23e49d64d2f4f.php
  84. 4
      niucloud/runtime/cache/0f/031b5cb7088c6004d3b5522558e3ee.php
  85. 4
      niucloud/runtime/cache/10/d14b034379d95ab08972c164bd0273.php
  86. 4
      niucloud/runtime/cache/13/0f87a1a4853b499cad67dae67fbbc5.php
  87. 4
      niucloud/runtime/cache/1a/fde0018bb1f6dadf6e9cc67514074e.php
  88. 4
      niucloud/runtime/cache/1f/893a713f7527421da280edd52452e1.php
  89. 2
      niucloud/runtime/cache/20/336a007c8134208722cf4e14270f07.php
  90. 4
      niucloud/runtime/cache/25/380f91a13166c6be2a0a568ff0aba5.php
  91. 2
      niucloud/runtime/cache/2c/e25dcb326df717900650d384ad7cf0.php
  92. 2
      niucloud/runtime/cache/32/0a87fb2f5a7e9725055a2c99bd1e51.php
  93. 4
      niucloud/runtime/cache/33/90cfdce4f303504facffc42620c48f.php
  94. 4
      niucloud/runtime/cache/3c/e760faa975bb7ccb960047660d6e14.php
  95. 4
      niucloud/runtime/cache/47/0f6e29f334d3244ee0749eb9b1a151.php
  96. 4
      niucloud/runtime/cache/48/d6f2efc72c165d1f15db38570485f6.php
  97. 4
      niucloud/runtime/cache/65/00bade063d7694b05ef06dcbf711a5.php
  98. 4
      niucloud/runtime/cache/69/75acdbf213ccfe0e2f593a09691914.php
  99. 4
      niucloud/runtime/cache/69/a49e80c01c8ac6301283724181433f.php
  100. 4
      niucloud/runtime/cache/72/3ee2b5cca5d08bc4a333825c70f9c4.php

8
.gitignore

@ -1,3 +1,11 @@
/.project
/.vscode
/.settings
/.buildpath
*.log
*.txt
/.idea
# Build and Release Folders
bin-debug/
bin-release/

2
admin/.env.development

@ -1,5 +1,5 @@
# api请求地址
VITE_APP_BASE_URL='http://146.56.228.75:20021/adminapi/'
VITE_APP_BASE_URL='http://zhjw.cc/adminapi/'
# 图片服务器地址
VITE_IMG_DOMAIN=''

2
admin/auto-imports.d.ts

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

1
admin/components.d.ts

@ -22,6 +22,7 @@ declare module '@vue/runtime-core' {
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']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']

6
admin/src/addon/zhjw/api/articles.ts

@ -1,5 +1,11 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- zhjw_articles
/**
*

62
admin/src/addon/zhjw/api/contracts.ts

@ -0,0 +1,62 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- zhjw_contracts
/**
*
* @param params
* @returns
*/
export function getContractsList(params: Record<string, any>) {
return request.get(`zhjw/contracts`, {params})
}
/**
*
* @param id id
* @returns
*/
export function getContractsInfo(id: number) {
return request.get(`zhjw/contracts/${id}`);
}
/**
*
* @param params
* @returns
*/
export function addContracts(params: Record<string, any>) {
return request.post('zhjw/contracts', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @param params
* @returns
*/
export function editContracts(params: Record<string, any>) {
return request.put(`zhjw/contracts/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @returns
*/
export function deleteContracts(id: number) {
return request.delete(`zhjw/contracts/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithUsersList(params: Record<string,any>){
return request.get('zhjw/users_all', {params})
}
// USER_CODE_END -- zhjw_contracts

56
admin/src/addon/zhjw/api/orders.ts

@ -0,0 +1,56 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- zhjw_orders
/**
* -
* @param params
* @returns
*/
export function getOrdersList(params: Record<string, any>) {
return request.get(`zhjw/orders`, {params})
}
/**
* -
* @param id -id
* @returns
*/
export function getOrdersInfo(id: number) {
return request.get(`zhjw/orders/${id}`);
}
/**
* -
* @param params
* @returns
*/
export function addOrders(params: Record<string, any>) {
return request.post('zhjw/orders', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* -
* @param id
* @param params
* @returns
*/
export function editOrders(params: Record<string, any>) {
return request.put(`zhjw/orders/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* -
* @param id
* @returns
*/
export function deleteOrders(id: number) {
return request.delete(`zhjw/orders/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithMemberList(params: Record<string,any>){
return request.get('zhjw/member_all', {params})
}export function getWithContractsList(params: Record<string,any>){
return request.get('zhjw/contracts_all', {params})
}
// USER_CODE_END -- zhjw_orders

58
admin/src/addon/zhjw/api/students.ts

@ -0,0 +1,58 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- zhjw_students
/**
*
* @param params
* @returns
*/
export function getStudentsList(params: Record<string, any>) {
return request.get(`zhjw/students`, {params})
}
/**
*
* @param id id
* @returns
*/
export function getStudentsInfo(id: number) {
return request.get(`zhjw/students/${id}`);
}
/**
*
* @param params
* @returns
*/
export function addStudents(params: Record<string, any>) {
return request.post('zhjw/students', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @param params
* @returns
*/
export function editStudents(params: Record<string, any>) {
return request.put(`zhjw/students/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @returns
*/
export function deleteStudents(id: number) {
return request.delete(`zhjw/students/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithUsersList(params: Record<string,any>){
return request.get('zhjw/users_all', {params})
}
// USER_CODE_END -- zhjw_students

62
admin/src/addon/zhjw/api/users.ts

@ -0,0 +1,62 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- zhjw_users
/**
*
* @param params
* @returns
*/
export function getUsersList(params: Record<string, any>) {
return request.get(`zhjw/users`, {params})
}
/**
*
* @param member_id member_id
* @returns
*/
export function getUsersInfo(member_id: number) {
return request.get(`zhjw/users/${member_id}`);
}
/**
*
* @param params
* @returns
*/
export function addUsers(params: Record<string, any>) {
return request.post('zhjw/users', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param member_id
* @param params
* @returns
*/
export function editUsers(params: Record<string, any>) {
return request.put(`zhjw/users/${params.member_id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param member_id
* @returns
*/
export function deleteUsers(member_id: number) {
return request.delete(`zhjw/users/${member_id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithUsersList(params: Record<string,any>){
return request.get('zhjw/users_all', {params})
}
// USER_CODE_END -- zhjw_users

7
admin/src/addon/zhjw/lang/zh-cn/articles.articles.json

@ -1,14 +1,17 @@
{
"id":"序号",
"title":"标题",
"titlePlaceholder":"请输入标题",
"content":"内容",
"contentPlaceholder":"请输入内容",
"category":"文章分类",
"categoryPlaceholder":"请输入文章分类",
"publisherId":"发布人",
"publisherIdPlaceholder":"全部",
"status":"状态",
"statusPlaceholder":"请输入状态",
"createTime":"添加时间",
"createTimePlaceholder":"请输入添加时间",
"updateTime":"更新时间",
"updateTimePlaceholder":"请输入更新时间",
"addArticles":"添加文章管理",
"updateArticles":"编辑文章管理",
"articlesDeleteTips":"确定要删除该数据吗?",

2
admin/src/addon/zhjw/lang/zh-cn/articles.articles_edit.json

@ -8,7 +8,7 @@
"contentPlaceholder":"请输入内容",
"categoryPlaceholder":"请选择文章分类",
"publisherIdPlaceholder":"请选择发布人",
"statusPlaceholder":"请输入状态",
"statusPlaceholder":"请选择状态",
"addArticles":"添加文章管理",
"updateArticles":"编辑文章管理",
"articlesDeleteTips":"确定要删除该文章管理吗?"

21
admin/src/addon/zhjw/lang/zh-cn/contracts.contracts.json

@ -0,0 +1,21 @@
{
"id":"序号",
"studentId":"学员",
"studentIdPlaceholder":"全部",
"title":"合同名称",
"titlePlaceholder":"请输入合同名称",
"startDate":"生效日期",
"startDatePlaceholder":"请输入生效日期",
"endDate":"终止日期",
"endDatePlaceholder":"请输入终止日期",
"status":"状态",
"statusPlaceholder":"请输入状态",
"createTime":"添加时间",
"createTimePlaceholder":"请输入添加时间",
"updateTime":"更新时间",
"addContracts":"添加合同管理",
"updateContracts":"编辑合同管理",
"contractsDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

19
admin/src/addon/zhjw/lang/zh-cn/contracts.contracts_edit.json

@ -0,0 +1,19 @@
{
"studentId":"学员",
"title":"合同名称",
"content":"合同内容",
"fileData":"合同文件路径",
"startDate":"生效日期",
"endDate":"终止日期",
"status":"状态",
"studentIdPlaceholder":"请选择学员",
"titlePlaceholder":"请输入合同名称",
"contentPlaceholder":"请输入合同内容",
"fileDataPlaceholder":"请输入合同文件路径",
"startDatePlaceholder":"请选择生效日期",
"endDatePlaceholder":"请选择终止日期",
"statusPlaceholder":"请选择状态",
"addContracts":"添加合同管理",
"updateContracts":"编辑合同管理",
"contractsDeleteTips":"确定要删除该合同管理吗?"
}

26
admin/src/addon/zhjw/lang/zh-cn/orders.orders.json

@ -0,0 +1,26 @@
{
"id":"序号",
"studentId":"学员",
"studentIdPlaceholder":"全部",
"contractId":"关联合同",
"contractIdPlaceholder":"全部",
"amount":"订单金额",
"amountPlaceholder":"请输入订单金额",
"orderType":"订单类型",
"orderTypePlaceholder":"请输入订单类型",
"payType":"支付类型",
"payTypePlaceholder":"请输入支付类型",
"paymentStatus":"支付状态",
"paymentStatusPlaceholder":"请输入支付状态",
"paymentTime":"支付时间",
"paymentTimePlaceholder":"请输入支付时间",
"createTime":"添加时间",
"createTimePlaceholder":"请输入添加时间",
"updateTime":"更新时间",
"isDeleted":"是否删除",
"addOrders":"添加智慧教务-订单管理",
"updateOrders":"编辑智慧教务-订单管理",
"ordersDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

19
admin/src/addon/zhjw/lang/zh-cn/orders.orders_edit.json

@ -0,0 +1,19 @@
{
"studentId":"学员",
"contractId":"关联合同",
"amount":"订单金额",
"orderType":"订单类型",
"payType":"支付类型",
"paymentStatus":"支付状态",
"paymentTime":"支付时间",
"studentIdPlaceholder":"请选择学员",
"contractIdPlaceholder":"请选择关联合同",
"amountPlaceholder":"请输入订单金额",
"orderTypePlaceholder":"请选择订单类型",
"payTypePlaceholder":"请选择支付类型",
"paymentStatusPlaceholder":"请选择支付状态",
"paymentTimePlaceholder":"请选择支付时间",
"addOrders":"添加智慧教务-订单管理",
"updateOrders":"编辑智慧教务-订单管理",
"ordersDeleteTips":"确定要删除该智慧教务-订单管理吗?"
}

25
admin/src/addon/zhjw/lang/zh-cn/students.students.json

@ -0,0 +1,25 @@
{
"id":"序号",
"name":"姓名",
"namePlaceholder":"请输入姓名",
"userId":"关联用户",
"userIdPlaceholder":"全部",
"haveStudyTime":"学员有效学时",
"haveStudyTimePlaceholder":"请输入学员有效学时",
"endStudyTime":"学员完成学时",
"endStudyTimePlaceholder":"请输入学员完成学时",
"emergencyContact":"紧急联系人",
"emergencyContactPlaceholder":"请输入紧急联系人",
"level":"学员等级",
"levelPlaceholder":"请输入学员等级",
"status":"状态",
"statusPlaceholder":"请输入状态",
"createTime":"添加时间",
"createTimePlaceholder":"请输入添加时间",
"updateTime":"更新时间",
"addStudents":"添加学员管理",
"updateStudents":"编辑学员管理",
"studentsDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

19
admin/src/addon/zhjw/lang/zh-cn/students.students_edit.json

@ -0,0 +1,19 @@
{
"name":"姓名",
"userId":"关联用户",
"haveStudyTime":"学员有效学时",
"endStudyTime":"学员完成学时",
"emergencyContact":"紧急联系人",
"level":"学员等级",
"status":"状态",
"namePlaceholder":"请输入姓名",
"userIdPlaceholder":"请选择关联用户",
"haveStudyTimePlaceholder":"请输入学员有效学时",
"endStudyTimePlaceholder":"请输入学员完成学时",
"emergencyContactPlaceholder":"请输入紧急联系人",
"levelPlaceholder":"请输入学员等级",
"statusPlaceholder":"请选择状态",
"addStudents":"添加学员管理",
"updateStudents":"编辑学员管理",
"studentsDeleteTips":"确定要删除该学员管理吗?"
}

88
admin/src/addon/zhjw/lang/zh-cn/users.users.json

@ -0,0 +1,88 @@
{
"memberId":"序号",
"memberNo":"会员编码",
"pid":"推广会员",
"username":"会员用户名",
"usernamePlaceholder":"请输入会员用户名",
"mobile":"手机号",
"mobilePlaceholder":"请输入手机号",
"password":"会员密码",
"nickname":"会员昵称",
"nicknamePlaceholder":"请输入会员昵称",
"headimg":"会员头像",
"memberLevel":"会员等级",
"memberLevelPlaceholder":"请输入会员等级",
"memberLabel":"会员标签",
"memberLabelPlaceholder":"请输入会员标签",
"wxOpenid":"微信用户openid",
"wxOpenidPlaceholder":"请输入微信用户openid",
"weappOpenid":"微信小程序openid",
"weappOpenidPlaceholder":"请输入微信小程序openid",
"wxUnionid":"微信unionid",
"wxUnionidPlaceholder":"请输入微信unionid",
"aliOpenid":"支付宝账户id",
"aliOpenidPlaceholder":"请输入支付宝账户id",
"douyinOpenid":"抖音小程序openid",
"douyinOpenidPlaceholder":"请输入抖音小程序openid",
"registerChannel":"注册来源",
"registerChannelPlaceholder":"请输入注册来源",
"registerType":"注册方式",
"registerTypePlaceholder":"请输入注册方式",
"loginIp":"当前登录ip",
"loginIpPlaceholder":"请输入当前登录ip",
"loginType":"当前登录的操作终端类型",
"loginTypePlaceholder":"请输入当前登录的操作终端类型",
"loginChannel":"登录渠道",
"loginChannelPlaceholder":"请输入登录渠道",
"loginCount":"登录次数",
"loginCountPlaceholder":"请输入登录次数",
"loginTime":"当前登录时间",
"loginTimePlaceholder":"请输入当前登录时间",
"lastVisitTime":"最后访问时间",
"lastVisitTimePlaceholder":"请输入最后访问时间",
"lastConsumTime":"最后消费时间",
"lastConsumTimePlaceholder":"请输入最后消费时间",
"sex":"性别",
"sexPlaceholder":"请输入性别",
"status":"用户状态",
"statusPlaceholder":"请输入用户状态",
"birthday":"出生日期",
"birthdayPlaceholder":"请输入出生日期",
"point":"可用积分",
"pointPlaceholder":"请输入可用积分",
"pointGet":"累计获取积分",
"pointGetPlaceholder":"请输入累计获取积分",
"balance":"可用余额",
"balancePlaceholder":"请输入可用余额",
"balanceGet":"累计获取余额",
"balanceGetPlaceholder":"请输入累计获取余额",
"money":"可用余额(可提现)",
"moneyPlaceholder":"请输入可用余额(可提现)",
"moneyGet":"累计获取余额(可提现)",
"moneyGetPlaceholder":"请输入累计获取余额(可提现)",
"moneyCashOuting":"提现中余额(可提现)",
"moneyCashOutingPlaceholder":"请输入提现中余额(可提现)",
"growth":"成长值",
"growthPlaceholder":"请输入成长值",
"growthGet":"累计获得成长值",
"growthGetPlaceholder":"请输入累计获得成长值",
"commission":"当前佣金",
"commissionPlaceholder":"请输入当前佣金",
"commissionGet":"佣金获取",
"commissionGetPlaceholder":"请输入佣金获取",
"commissionCashOuting":"提现中佣金",
"commissionCashOutingPlaceholder":"请输入提现中佣金",
"isMember":"是否是会员",
"isMemberPlaceholder":"请输入是否是会员",
"memberTime":"成为会员时间",
"memberTimePlaceholder":"请输入成为会员时间",
"address":"详细地址",
"createTime":"注册时间",
"createTimePlaceholder":"请输入注册时间",
"updateTime":"修改时间",
"addUsers":"添加用户管理",
"updateUsers":"编辑用户管理",
"usersDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

87
admin/src/addon/zhjw/lang/zh-cn/users.users_edit.json

@ -0,0 +1,87 @@
{
"memberNo":"会员编码",
"pid":"推广会员",
"username":"会员用户名",
"mobile":"手机号",
"password":"会员密码",
"nickname":"会员昵称",
"headimg":"会员头像",
"memberLevel":"会员等级",
"memberLabel":"会员标签",
"wxOpenid":"微信用户openid",
"weappOpenid":"微信小程序openid",
"wxUnionid":"微信unionid",
"aliOpenid":"支付宝账户id",
"douyinOpenid":"抖音小程序openid",
"registerChannel":"注册来源",
"registerType":"注册方式",
"loginIp":"当前登录ip",
"loginType":"当前登录的操作终端类型",
"loginChannel":"登录渠道",
"loginCount":"登录次数",
"loginTime":"当前登录时间",
"lastVisitTime":"最后访问时间",
"lastConsumTime":"最后消费时间",
"sex":"性别",
"status":"用户状态",
"birthday":"出生日期",
"point":"可用积分",
"pointGet":"累计获取积分",
"balance":"可用余额",
"balanceGet":"累计获取余额",
"money":"可用余额(可提现)",
"moneyGet":"累计获取余额(可提现)",
"moneyCashOuting":"提现中余额(可提现)",
"growth":"成长值",
"growthGet":"累计获得成长值",
"commission":"当前佣金",
"commissionGet":"佣金获取",
"commissionCashOuting":"提现中佣金",
"isMember":"是否是会员",
"memberTime":"成为会员时间",
"address":"详细地址",
"memberNoPlaceholder":"请输入会员编码",
"pidPlaceholder":"请选择推广会员",
"usernamePlaceholder":"请输入会员用户名",
"mobilePlaceholder":"请输入手机号",
"passwordPlaceholder":"请输入会员密码",
"nicknamePlaceholder":"请输入会员昵称",
"headimgPlaceholder":"请上传会员头像",
"memberLevelPlaceholder":"请输入会员等级",
"memberLabelPlaceholder":"请输入会员标签",
"wxOpenidPlaceholder":"请输入微信用户openid",
"weappOpenidPlaceholder":"请输入微信小程序openid",
"wxUnionidPlaceholder":"请输入微信unionid",
"aliOpenidPlaceholder":"请输入支付宝账户id",
"douyinOpenidPlaceholder":"请输入抖音小程序openid",
"registerChannelPlaceholder":"请输入注册来源",
"registerTypePlaceholder":"请输入注册方式",
"loginIpPlaceholder":"请输入当前登录ip",
"loginTypePlaceholder":"请输入当前登录的操作终端类型",
"loginChannelPlaceholder":"请输入登录渠道",
"loginCountPlaceholder":"请输入登录次数",
"loginTimePlaceholder":"请输入当前登录时间",
"lastVisitTimePlaceholder":"请输入最后访问时间",
"lastConsumTimePlaceholder":"请输入最后消费时间",
"sexPlaceholder":"请选择性别",
"statusPlaceholder":"请选择用户状态",
"birthdayPlaceholder":"请选择出生日期",
"pointPlaceholder":"请输入可用积分",
"pointGetPlaceholder":"请输入累计获取积分",
"balancePlaceholder":"请输入可用余额",
"balanceGetPlaceholder":"请输入累计获取余额",
"moneyPlaceholder":"请输入可用余额(可提现)",
"moneyGetPlaceholder":"请输入累计获取余额(可提现)",
"moneyCashOutingPlaceholder":"请输入提现中余额(可提现)",
"growthPlaceholder":"请输入成长值",
"growthGetPlaceholder":"请输入累计获得成长值",
"commissionPlaceholder":"请输入当前佣金",
"commissionGetPlaceholder":"请输入佣金获取",
"commissionCashOutingPlaceholder":"请输入提现中佣金",
"isMemberPlaceholder":"请选择是否是会员",
"memberTimePlaceholder":"请选择成为会员时间",
"addressPlaceholder":"请输入详细地址",
"addUsers":"添加用户管理",
"updateUsers":"编辑用户管理",
"usersDeleteTips":"确定要删除该用户管理吗?"
}

43
admin/src/addon/zhjw/views/articles/articles.vue

@ -14,9 +14,6 @@
<el-form-item :label="t('title')" prop="title">
<el-input v-model="articlesTable.searchParam.title" :placeholder="t('titlePlaceholder')" />
</el-form-item>
<el-form-item :label="t('content')" prop="content">
<el-input v-model="articlesTable.searchParam.content" :placeholder="t('contentPlaceholder')" />
</el-form-item>
<el-form-item :label="t('category')" prop="category">
<el-select class="w-[280px]" v-model="articlesTable.searchParam.category" clearable :placeholder="t('categoryPlaceholder')">
@ -36,8 +33,8 @@
<el-option
v-for="(item, index) in publisherIdList"
:key="index"
:label="item['uid']"
:value="item['real_name']"
:label="item['username']"
:value="item['uid']"
/>
</el-select>
</el-form-item>
@ -54,6 +51,16 @@
/>
</el-select>
</el-form-item>
<el-form-item :label="t('createTime')" prop="create_time">
<el-date-picker v-model="articlesTable.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 :label="t('updateTime')" prop="update_time">
<el-date-picker v-model="articlesTable.searchParam.update_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="loadArticlesList()">{{ t('search') }}</el-button>
@ -67,6 +74,8 @@
<template #empty>
<span>{{ !articlesTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="title" :label="t('title')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('category')" min-width="180" align="center" :show-overflow-tooltip="true">
@ -86,6 +95,18 @@
</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('updateTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.update_time || '' }}
</template>
</el-table-column>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
@ -127,10 +148,11 @@ let articlesTable = reactive({
data: [],
searchParam:{
"title":"",
"content":"",
"category":"",
"publisher_id":"",
"status":""
"status":"",
"create_time":[],
"update_time":[]
}
})
@ -149,7 +171,12 @@ const selectData = ref<any[]>([])
const statusDictList = async () => {
statusList.value = await (await useDictionary('is_radio')).data.dictionary
}
statusDictList();
statusDictList();
const is_deletedList = ref([] as any[])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
/**
* 获取文章管理列表

31
admin/src/addon/zhjw/views/articles/articles_edit.vue

@ -14,10 +14,9 @@
<el-input v-model="formData.title" clearable :placeholder="t('titlePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('content')" prop="content">
<el-input v-model="formData.content" clearable :placeholder="t('contentPlaceholder')" class="input-width" />
<el-form-item :label="t('content')" >
<editor v-model="formData.content" />
</el-form-item>
<el-form-item :label="t('category')" prop="category">
<el-select class="input-width" v-model="formData.category" clearable :placeholder="t('categoryPlaceholder')">
<el-option label="请选择" value=""></el-option>
@ -36,20 +35,22 @@
<el-option
v-for="(item, index) in publisherIdList"
:key="index"
:label="item['uid']"
:value="item['real_name']"
:label="item['username']"
:value="item['uid']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-radio-group v-model="formData.status" :placeholder="t('statusPlaceholder')">
<el-radio
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index" :label="item.value">
{{ item.name }}
</el-radio>
</el-radio-group>
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
@ -116,7 +117,13 @@ const selectData = ref<any[]>([])
statusList.value = await (await useDictionary('is_radio')).data.dictionary
}
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
let is_deletedList = ref([])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
watch(() => is_deletedList.value, () => { formData.is_deleted = is_deletedList.value[0].value })
const publisherIdList = ref([] as any[])

244
admin/src/addon/zhjw/views/contracts/contracts.vue

@ -0,0 +1,244 @@
<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('addContracts') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="contractsTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('studentId')" prop="student_id">
<el-select class="w-[280px]" v-model="contractsTable.searchParam.student_id" clearable :placeholder="t('studentIdPlaceholder')">
<el-option
v-for="(item, index) in studentIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('title')" prop="title">
<el-input v-model="contractsTable.searchParam.title" :placeholder="t('titlePlaceholder')" />
</el-form-item>
<el-form-item :label="t('startDate')" prop="start_date">
<el-date-picker v-model="contractsTable.searchParam.start_date" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item :label="t('endDate')" prop="end_date">
<el-date-picker v-model="contractsTable.searchParam.end_date" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-select class="w-[280px]" v-model="contractsTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
: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="contractsTable.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="loadContractsList()">{{ 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="contractsTable.data" size="large" v-loading="contractsTable.loading">
<template #empty>
<span>{{ !contractsTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="student_id_name" :label="t('studentId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="title" :label="t('title')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="start_date" :label="t('startDate')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="end_date" :label="t('endDate')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('status')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in statusList">
<div v-if="item.value == row.status">{{ 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('updateTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.update_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="contractsTable.page" v-model:page-size="contractsTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="contractsTable.total"
@size-change="loadContractsList()" @current-change="loadContractsList" />
</div>
</div>
</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 { getContractsList, deleteContracts, getWithUsersList } from '@/addon/zhjw/api/contracts'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let contractsTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam:{
"student_id":"",
"title":"",
"start_date":[],
"end_date":[],
"status":"",
"create_time":[]
}
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
const statusList = ref([] as any[])
const statusDictList = async () => {
statusList.value = await (await useDictionary('zhjw_contracts_status')).data.dictionary
}
statusDictList();
const is_deletedList = ref([] as any[])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
/**
* 获取合同管理列表
*/
const loadContractsList = (page: number = 1) => {
contractsTable.loading = true
contractsTable.page = page
getContractsList({
page: contractsTable.page,
limit: contractsTable.limit,
...contractsTable.searchParam
}).then(res => {
contractsTable.loading = false
contractsTable.data = res.data.data
contractsTable.total = res.data.total
}).catch(() => {
contractsTable.loading = false
})
}
loadContractsList()
const router = useRouter()
/**
* 添加合同管理
*/
const addEvent = () => {
router.push('/contracts/contracts_edit')
}
/**
* 编辑合同管理
* @param data
*/
const editEvent = (data: any) => {
router.push('/contracts/contracts_edit?id='+data.id)
}
/**
* 删除合同管理
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('contractsDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteContracts(id).then(() => {
loadContractsList()
}).catch(() => {
})
})
}
const studentIdList = ref([])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithUsersList({})).data
}
setStudentIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadContractsList()
}
</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>

243
admin/src/addon/zhjw/views/contracts/contracts_edit.vue

@ -0,0 +1,243 @@
<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="90px" ref="formRef" :rules="formRules" class="page-form">
<el-form-item :label="t('studentId')" prop="student_id">
<el-select class="input-width" v-model="formData.student_id" clearable :placeholder="t('studentIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in studentIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('title')" prop="title">
<el-input v-model="formData.title" clearable :placeholder="t('titlePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('content')" >
<editor v-model="formData.content" />
</el-form-item>
<el-form-item :label="t('fileData')">
<upload-file v-model="formData.file_data" />
</el-form-item>
<el-form-item :label="t('startDate')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.start_date"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('startDatePlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('endDate')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.end_date"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('endDatePlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('status')" >
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</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 { getContractsInfo,addContracts,editContracts, getWithUsersList } from '@/addon/zhjw/api/contracts';
import { useRoute } from 'vue-router'
const route = useRoute()
const id:number = parseInt(route.query.id);
const loading = ref(false)
const pageName = route.meta.title
/**
* 表单数据
*/
const initialFormData = {
id: 0,
student_id: '',
title: '',
content: '',
file_data: '',
start_date: '',
end_date: '',
status: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const setFormData = async (id:number = 0) => {
Object.assign(formData, initialFormData)
const data = await (await getContractsInfo(id)).data
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
if(id) setFormData(id);
const formRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
let statusList = ref([])
const statusDictList = async () => {
statusList.value = await (await useDictionary('zhjw_contracts_status')).data.dictionary
}
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
let is_deletedList = ref([])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
watch(() => is_deletedList.value, () => { formData.is_deleted = is_deletedList.value[0].value })
const studentIdList = ref([] as any[])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithUsersList({})).data
}
setStudentIdList()
//
const formRules = computed(() => {
return {
student_id: [
{ required: true, message: t('studentIdPlaceholder'), trigger: 'blur' },
]
,
title: [
{ required: true, message: t('titlePlaceholder'), trigger: 'blur' },
]
,
content: [
{ required: true, message: t('contentPlaceholder'), trigger: 'blur' },
]
,
file_data: [
{ required: true, message: t('fileDataPlaceholder'), trigger: 'blur' },
]
,
start_date: [
{ required: true, message: t('startDatePlaceholder'), trigger: 'blur' },
]
,
end_date: [
{ required: true, message: t('endDatePlaceholder'), trigger: 'blur' },
]
,
status: [
{ required: true, message: t('statusPlaceholder'), 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 = id ? editContracts : addContracts
save(data).then(res => {
loading.value = false
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()
}
</script>
<style lang="scss" scoped></style>

323
admin/src/addon/zhjw/views/orders/orders.vue

@ -0,0 +1,323 @@
<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('addOrders') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="ordersTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('studentId')" prop="student_id">
<el-select class="w-[280px]" v-model="ordersTable.searchParam.student_id" clearable :placeholder="t('studentIdPlaceholder')">
<el-option
v-for="(item, index) in studentIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('contractId')" prop="contract_id">
<el-select class="w-[280px]" v-model="ordersTable.searchParam.contract_id" clearable :placeholder="t('contractIdPlaceholder')">
<el-option
v-for="(item, index) in contractIdList"
:key="index"
:label="item['title']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('amount')" prop="amount">
<range-input v-model="ordersTable.searchParam.amount"/>
</el-form-item>
<el-form-item :label="t('orderType')" prop="order_type">
<el-select class="w-[280px]" v-model="ordersTable.searchParam.order_type" clearable :placeholder="t('orderTypePlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in order_typeList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('payType')" prop="pay_type">
<el-select class="w-[280px]" v-model="ordersTable.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('paymentStatus')" prop="payment_status">
<el-select class="w-[280px]" v-model="ordersTable.searchParam.payment_status" clearable :placeholder="t('paymentStatusPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in payment_statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('paymentTime')" prop="payment_time">
<el-date-picker v-model="ordersTable.searchParam.payment_time" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
: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="ordersTable.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="loadOrdersList()">{{ 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="ordersTable.data" size="large" v-loading="ordersTable.loading">
<template #empty>
<span>{{ !ordersTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="student_id_name" :label="t('studentId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="contract_id_name" :label="t('contractId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="amount" :label="t('amount')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('orderType')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in order_typeList">
<div v-if="item.value == row.order_type">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<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 :label="t('paymentStatus')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in payment_statusList">
<div v-if="item.value == row.payment_status">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column :label="t('paymentTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.payment_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('updateTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.update_time || '' }}
</template>
</el-table-column>
<el-table-column :label="t('isDeleted')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in is_deletedList">
<div v-if="item.value == row.is_deleted">{{ item.name }}</div>
</div>
</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="ordersTable.page" v-model:page-size="ordersTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="ordersTable.total"
@size-change="loadOrdersList()" @current-change="loadOrdersList" />
</div>
</div>
</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 { getOrdersList, deleteOrders, getWithMemberList, getWithContractsList } from '@/addon/zhjw/api/orders'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let ordersTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam:{
"student_id":"",
"contract_id":"",
"amount":[],
"order_type":"",
"pay_type":"",
"payment_status":"",
"payment_time":[],
"create_time":[]
}
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
const order_typeList = ref([] as any[])
const order_typeDictList = async () => {
order_typeList.value = await (await useDictionary('zhjw_order_type')).data.dictionary
}
order_typeDictList();
const pay_typeList = ref([] as any[])
const pay_typeDictList = async () => {
pay_typeList.value = await (await useDictionary('zhjw_pay_type')).data.dictionary
}
pay_typeDictList();
const payment_statusList = ref([] as any[])
const payment_statusDictList = async () => {
payment_statusList.value = await (await useDictionary('zhjw_payment_status')).data.dictionary
}
payment_statusDictList();
const is_deletedList = ref([] as any[])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
/**
* 获取智慧教务-订单管理列表
*/
const loadOrdersList = (page: number = 1) => {
ordersTable.loading = true
ordersTable.page = page
getOrdersList({
page: ordersTable.page,
limit: ordersTable.limit,
...ordersTable.searchParam
}).then(res => {
ordersTable.loading = false
ordersTable.data = res.data.data
ordersTable.total = res.data.total
}).catch(() => {
ordersTable.loading = false
})
}
loadOrdersList()
const router = useRouter()
/**
* 添加智慧教务-订单管理
*/
const addEvent = () => {
router.push('/orders/orders_edit')
}
/**
* 编辑智慧教务-订单管理
* @param data
*/
const editEvent = (data: any) => {
router.push('/orders/orders_edit?id='+data.id)
}
/**
* 删除智慧教务-订单管理
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('ordersDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteOrders(id).then(() => {
loadOrdersList()
}).catch(() => {
})
})
}
const studentIdList = ref([])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithMemberList({})).data
}
setStudentIdList()
const contractIdList = ref([])
const setContractIdList = async () => {
contractIdList.value = await (await getWithContractsList({})).data
}
setContractIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadOrdersList()
}
</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>

279
admin/src/addon/zhjw/views/orders/orders_edit.vue

@ -0,0 +1,279 @@
<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="90px" ref="formRef" :rules="formRules" class="page-form">
<el-form-item :label="t('studentId')" prop="student_id">
<el-select class="input-width" v-model="formData.student_id" clearable :placeholder="t('studentIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in studentIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('contractId')" prop="contract_id">
<el-select class="input-width" v-model="formData.contract_id" clearable :placeholder="t('contractIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in contractIdList"
:key="index"
:label="item['title']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('amount')" prop="amount">
<el-input-number v-model="formData.amount" clearable :placeholder="t('amountPlaceholder')" class="input-width" :min = "0.01" max = "999999" />
</el-form-item>
<el-form-item :label="t('orderType')" prop="order_type">
<el-select class="input-width" v-model="formData.order_type" clearable :placeholder="t('orderTypePlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in order_typeList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</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('paymentStatus')" prop="payment_status">
<el-select class="input-width" v-model="formData.payment_status" clearable :placeholder="t('paymentStatusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in payment_statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('paymentTime')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.payment_time"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('paymentTimePlaceholder')">
</el-date-picker>
</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 { getOrdersInfo,addOrders,editOrders, getWithMemberList, getWithContractsList } from '@/addon/zhjw/api/orders';
import { useRoute } from 'vue-router'
const route = useRoute()
const id:number = parseInt(route.query.id);
const loading = ref(false)
const pageName = route.meta.title
/**
* 表单数据
*/
const initialFormData = {
id: 0,
student_id: '',
contract_id: '',
amount: '',
order_type: '',
pay_type: '',
payment_status: '',
payment_time: 0,
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const setFormData = async (id:number = 0) => {
Object.assign(formData, initialFormData)
const data = await (await getOrdersInfo(id)).data
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
if(id) setFormData(id);
const formRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
let order_typeList = ref([])
const order_typeDictList = async () => {
order_typeList.value = await (await useDictionary('zhjw_order_type')).data.dictionary
}
order_typeDictList();
watch(() => order_typeList.value, () => { formData.order_type = order_typeList.value[0].value })
let pay_typeList = ref([])
const pay_typeDictList = async () => {
pay_typeList.value = await (await useDictionary('zhjw_pay_type')).data.dictionary
}
pay_typeDictList();
watch(() => pay_typeList.value, () => { formData.pay_type = pay_typeList.value[0].value })
let payment_statusList = ref([])
const payment_statusDictList = async () => {
payment_statusList.value = await (await useDictionary('zhjw_payment_status')).data.dictionary
}
payment_statusDictList();
watch(() => payment_statusList.value, () => { formData.payment_status = payment_statusList.value[0].value })
let is_deletedList = ref([])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
watch(() => is_deletedList.value, () => { formData.is_deleted = is_deletedList.value[0].value })
const studentIdList = ref([] as any[])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithMemberList({})).data
}
setStudentIdList()
const contractIdList = ref([] as any[])
const setContractIdList = async () => {
contractIdList.value = await (await getWithContractsList({})).data
}
setContractIdList()
//
const formRules = computed(() => {
return {
student_id: [
{ required: true, message: t('studentIdPlaceholder'), trigger: 'blur' },
]
,
contract_id: [
{ required: true, message: t('contractIdPlaceholder'), trigger: 'blur' },
]
,
amount: [
{ required: true, message: t('amountPlaceholder'), trigger: 'blur' },
{ validator: (rule: any, value: string, callback: any) => { if (value && !/^\d{0.01,999999}$/.test(value)) { callback(new Error(t('generateBetween')))} else { callback() }}},
]
,
order_type: [
{ required: true, message: t('orderTypePlaceholder'), trigger: 'blur' },
]
,
pay_type: [
{ required: true, message: t('payTypePlaceholder'), trigger: 'blur' },
]
,
payment_status: [
{ required: true, message: t('paymentStatusPlaceholder'), trigger: 'blur' },
]
,
payment_time: [
{ required: true, message: t('paymentTimePlaceholder'), 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 = id ? editOrders : addOrders
save(data).then(res => {
loading.value = false
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()
}
</script>
<style lang="scss" scoped></style>

249
admin/src/addon/zhjw/views/students/students.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('addStudents') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="studentsTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('name')" prop="name">
<el-input v-model="studentsTable.searchParam.name" :placeholder="t('namePlaceholder')" />
</el-form-item>
<el-form-item :label="t('userId')" prop="user_id">
<el-select class="w-[280px]" v-model="studentsTable.searchParam.user_id" clearable :placeholder="t('userIdPlaceholder')">
<el-option
v-for="(item, index) in userIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('haveStudyTime')" prop="have_study_time">
<range-input v-model="studentsTable.searchParam.have_study_time"/>
</el-form-item>
<el-form-item :label="t('endStudyTime')" prop="end_study_time">
<range-input v-model="studentsTable.searchParam.end_study_time"/>
</el-form-item>
<el-form-item :label="t('emergencyContact')" prop="emergency_contact">
<el-input v-model="studentsTable.searchParam.emergency_contact" :placeholder="t('emergencyContactPlaceholder')" />
</el-form-item>
<el-form-item :label="t('level')" prop="level">
<el-input v-model="studentsTable.searchParam.level" :placeholder="t('levelPlaceholder')" />
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-select class="w-[280px]" v-model="studentsTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
: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="studentsTable.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="loadStudentsList()">{{ 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="studentsTable.data" size="large" v-loading="studentsTable.loading">
<template #empty>
<span>{{ !studentsTable.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="user_id_name" :label="t('userId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="have_study_time" :label="t('haveStudyTime')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="end_study_time" :label="t('endStudyTime')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="emergency_contact" :label="t('emergencyContact')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="level" :label="t('level')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('status')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in statusList">
<div v-if="item.value == row.status">{{ 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('updateTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.update_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="studentsTable.page" v-model:page-size="studentsTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="studentsTable.total"
@size-change="loadStudentsList()" @current-change="loadStudentsList" />
</div>
</div>
</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 { getStudentsList, deleteStudents, getWithUsersList } from '@/addon/zhjw/api/students'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let studentsTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam:{
"name":"",
"user_id":"",
"have_study_time":[],
"end_study_time":[],
"emergency_contact":"",
"level":"",
"status":"",
"create_time":[]
}
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
const statusList = ref([] as any[])
const statusDictList = async () => {
statusList.value = await (await useDictionary('students_status')).data.dictionary
}
statusDictList();
/**
* 获取学员管理列表
*/
const loadStudentsList = (page: number = 1) => {
studentsTable.loading = true
studentsTable.page = page
getStudentsList({
page: studentsTable.page,
limit: studentsTable.limit,
...studentsTable.searchParam
}).then(res => {
studentsTable.loading = false
studentsTable.data = res.data.data
studentsTable.total = res.data.total
}).catch(() => {
studentsTable.loading = false
})
}
loadStudentsList()
const router = useRouter()
/**
* 添加学员管理
*/
const addEvent = () => {
router.push('/students/students_edit')
}
/**
* 编辑学员管理
* @param data
*/
const editEvent = (data: any) => {
router.push('/students/students_edit?id='+data.id)
}
/**
* 删除学员管理
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('studentsDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteStudents(id).then(() => {
loadStudentsList()
}).catch(() => {
})
})
}
const userIdList = ref([])
const setUserIdList = async () => {
userIdList.value = await (await getWithUsersList({})).data
}
setUserIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadStudentsList()
}
</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>

226
admin/src/addon/zhjw/views/students/students_edit.vue

@ -0,0 +1,226 @@
<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="90px" ref="formRef" :rules="formRules" class="page-form">
<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('userId')" prop="user_id">
<el-select class="input-width" v-model="formData.user_id" clearable :placeholder="t('userIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in userIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('haveStudyTime')" >
<el-input-number v-model="formData.have_study_time" clearable :placeholder="t('haveStudyTimePlaceholder')" class="input-width" :min = "0" max = "999999" />
</el-form-item>
<el-form-item :label="t('endStudyTime')" >
<el-input-number v-model="formData.end_study_time" clearable :placeholder="t('endStudyTimePlaceholder')" class="input-width" :min = "0" max = "999999" />
</el-form-item>
<el-form-item :label="t('emergencyContact')" >
<el-input v-model="formData.emergency_contact" clearable :placeholder="t('emergencyContactPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('level')" >
<el-input v-model="formData.level" clearable :placeholder="t('levelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</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 { getStudentsInfo,addStudents,editStudents, getWithUsersList } from '@/addon/zhjw/api/students';
import { useRoute } from 'vue-router'
const route = useRoute()
const id:number = parseInt(route.query.id);
const loading = ref(false)
const pageName = route.meta.title
/**
* 表单数据
*/
const initialFormData = {
id: 0,
name: '',
user_id: '',
have_study_time: '',
end_study_time: '',
emergency_contact: '',
level: '',
status: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const setFormData = async (id:number = 0) => {
Object.assign(formData, initialFormData)
const data = await (await getStudentsInfo(id)).data
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
if(id) setFormData(id);
const formRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
let statusList = ref([])
const statusDictList = async () => {
statusList.value = await (await useDictionary('students_status')).data.dictionary
}
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
const userIdList = ref([] as any[])
const setUserIdList = async () => {
userIdList.value = await (await getWithUsersList({})).data
}
setUserIdList()
//
const formRules = computed(() => {
return {
name: [
{ required: true, message: t('namePlaceholder'), trigger: 'blur' },
]
,
user_id: [
{ required: true, message: t('userIdPlaceholder'), trigger: 'blur' },
]
,
have_study_time: [
{ required: true, message: t('haveStudyTimePlaceholder'), trigger: 'blur' },
{ validator: (rule: any, value: string, callback: any) => { if (value && !/^\d{0,999999}$/.test(value)) { callback(new Error(t('generateBetween')))} else { callback() }}},
]
,
end_study_time: [
{ required: true, message: t('endStudyTimePlaceholder'), trigger: 'blur' },
{ validator: (rule: any, value: string, callback: any) => { if (value && !/^\d{0,999999}$/.test(value)) { callback(new Error(t('generateBetween')))} else { callback() }}},
]
,
emergency_contact: [
{ required: true, message: t('emergencyContactPlaceholder'), trigger: 'blur' },
]
,
level: [
{ required: true, message: t('levelPlaceholder'), trigger: 'blur' },
]
,
status: [
{ required: true, message: t('statusPlaceholder'), 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 = id ? editStudents : addStudents
save(data).then(res => {
loading.value = false
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()
}
</script>
<style lang="scss" scoped></style>

615
admin/src/addon/zhjw/views/users/components/users-edit.vue

@ -0,0 +1,615 @@
<template>
<el-dialog v-model="showDialog" :title="formData.member_id ? t('updateUsers') : t('addUsers')" 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('memberNo')" >
<el-input v-model="formData.member_no" clearable :placeholder="t('memberNoPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('pid')" >
<el-select class="input-width" v-model="formData.pid" clearable :placeholder="t('pidPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in pidList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('username')" prop="username">
<el-input v-model="formData.username" clearable :placeholder="t('usernamePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('mobile')" prop="mobile">
<el-input v-model="formData.mobile" clearable :placeholder="t('mobilePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('password')" prop="password">
<el-input v-model="formData.password" clearable :placeholder="t('passwordPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('nickname')" prop="nickname">
<el-input v-model="formData.nickname" clearable :placeholder="t('nicknamePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('headimg')">
<upload-image v-model="formData.headimg" />
</el-form-item>
<el-form-item :label="t('memberLevel')" prop="member_level">
<el-input v-model="formData.member_level" clearable :placeholder="t('memberLevelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('memberLabel')" prop="member_label">
<el-input v-model="formData.member_label" clearable :placeholder="t('memberLabelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('wxOpenid')" >
<el-input v-model="formData.wx_openid" clearable :placeholder="t('wxOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('weappOpenid')" >
<el-input v-model="formData.weapp_openid" clearable :placeholder="t('weappOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('wxUnionid')" >
<el-input v-model="formData.wx_unionid" clearable :placeholder="t('wxUnionidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('aliOpenid')" >
<el-input v-model="formData.ali_openid" clearable :placeholder="t('aliOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('douyinOpenid')" >
<el-input v-model="formData.douyin_openid" clearable :placeholder="t('douyinOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('registerChannel')" >
<el-input v-model="formData.register_channel" clearable :placeholder="t('registerChannelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('registerType')" >
<el-input v-model="formData.register_type" clearable :placeholder="t('registerTypePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginIp')" >
<el-input v-model="formData.login_ip" clearable :placeholder="t('loginIpPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginType')" >
<el-input v-model="formData.login_type" clearable :placeholder="t('loginTypePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginChannel')" >
<el-input v-model="formData.login_channel" clearable :placeholder="t('loginChannelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginCount')" >
<el-input v-model="formData.login_count" clearable :placeholder="t('loginCountPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginTime')" >
<el-input v-model="formData.login_time" clearable :placeholder="t('loginTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('lastVisitTime')" >
<el-input v-model="formData.last_visit_time" clearable :placeholder="t('lastVisitTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('lastConsumTime')" >
<el-input v-model="formData.last_consum_time" clearable :placeholder="t('lastConsumTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('sex')" prop="sex">
<el-select class="input-width" v-model="formData.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('status')" prop="status">
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</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="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('birthdayPlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('point')" >
<el-input v-model="formData.point" clearable :placeholder="t('pointPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('pointGet')" >
<el-input v-model="formData.point_get" clearable :placeholder="t('pointGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('balance')" >
<el-input v-model="formData.balance" clearable :placeholder="t('balancePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('balanceGet')" >
<el-input v-model="formData.balance_get" clearable :placeholder="t('balanceGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('money')" >
<el-input v-model="formData.money" clearable :placeholder="t('moneyPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('moneyGet')" >
<el-input v-model="formData.money_get" clearable :placeholder="t('moneyGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('moneyCashOuting')" >
<el-input v-model="formData.money_cash_outing" clearable :placeholder="t('moneyCashOutingPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('growth')" >
<el-input v-model="formData.growth" clearable :placeholder="t('growthPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('growthGet')" >
<el-input v-model="formData.growth_get" clearable :placeholder="t('growthGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commission')" >
<el-input v-model="formData.commission" clearable :placeholder="t('commissionPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commissionGet')" >
<el-input v-model="formData.commission_get" clearable :placeholder="t('commissionGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commissionCashOuting')" >
<el-input v-model="formData.commission_cash_outing" clearable :placeholder="t('commissionCashOutingPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('isMember')" prop="is_member">
<el-select class="input-width" v-model="formData.is_member" clearable :placeholder="t('isMemberPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in is_memberList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('memberTime')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.member_time"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('memberTimePlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('address')" >
<el-input v-model="formData.address" clearable :placeholder="t('addressPlaceholder')" 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 { addUsers, editUsers, getUsersInfo, getWithUsersList } from '@/addon/zhjw/api/users'
let showDialog = ref(false)
const loading = ref(false)
/**
* 表单数据
*/
const initialFormData = {
member_id: '',
member_no: '',
pid: '',
username: '',
mobile: '',
password: '',
nickname: '',
headimg: '',
member_level: '',
member_label: '',
wx_openid: '',
weapp_openid: '',
wx_unionid: '',
ali_openid: '',
douyin_openid: '',
register_channel: '',
register_type: '',
login_ip: '',
login_type: '',
login_channel: '',
login_count: '',
login_time: '',
last_visit_time: '',
last_consum_time: '',
sex: '',
status: '',
birthday: '',
point: '',
point_get: '',
balance: '',
balance_get: '',
money: '',
money_get: '',
money_cash_outing: '',
growth: '',
growth_get: '',
commission: '',
commission_get: '',
commission_cash_outing: '',
is_member: '',
member_time: '',
address: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const formRef = ref<FormInstance>()
//
const formRules = computed(() => {
return {
member_no: [
{ required: true, message: t('memberNoPlaceholder'), trigger: 'blur' },
]
,
pid: [
{ required: true, message: t('pidPlaceholder'), trigger: 'blur' },
]
,
username: [
{ required: true, message: t('usernamePlaceholder'), trigger: 'blur' },
]
,
mobile: [
{ required: true, message: t('mobilePlaceholder'), trigger: 'blur' },
]
,
password: [
{ required: true, message: t('passwordPlaceholder'), trigger: 'blur' },
]
,
nickname: [
{ required: true, message: t('nicknamePlaceholder'), trigger: 'blur' },
]
,
headimg: [
{ required: true, message: t('headimgPlaceholder'), trigger: 'blur' },
]
,
member_level: [
{ required: true, message: t('memberLevelPlaceholder'), trigger: 'blur' },
]
,
member_label: [
{ required: true, message: t('memberLabelPlaceholder'), trigger: 'blur' },
]
,
wx_openid: [
{ required: true, message: t('wxOpenidPlaceholder'), trigger: 'blur' },
]
,
weapp_openid: [
{ required: true, message: t('weappOpenidPlaceholder'), trigger: 'blur' },
]
,
wx_unionid: [
{ required: true, message: t('wxUnionidPlaceholder'), trigger: 'blur' },
]
,
ali_openid: [
{ required: true, message: t('aliOpenidPlaceholder'), trigger: 'blur' },
]
,
douyin_openid: [
{ required: true, message: t('douyinOpenidPlaceholder'), trigger: 'blur' },
]
,
register_channel: [
{ required: true, message: t('registerChannelPlaceholder'), trigger: 'blur' },
]
,
register_type: [
{ required: true, message: t('registerTypePlaceholder'), trigger: 'blur' },
]
,
login_ip: [
{ required: true, message: t('loginIpPlaceholder'), trigger: 'blur' },
]
,
login_type: [
{ required: true, message: t('loginTypePlaceholder'), trigger: 'blur' },
]
,
login_channel: [
{ required: true, message: t('loginChannelPlaceholder'), trigger: 'blur' },
]
,
login_count: [
{ required: true, message: t('loginCountPlaceholder'), trigger: 'blur' },
]
,
login_time: [
{ required: true, message: t('loginTimePlaceholder'), trigger: 'blur' },
]
,
last_visit_time: [
{ required: true, message: t('lastVisitTimePlaceholder'), trigger: 'blur' },
]
,
last_consum_time: [
{ required: true, message: t('lastConsumTimePlaceholder'), trigger: 'blur' },
]
,
sex: [
{ required: true, message: t('sexPlaceholder'), trigger: 'blur' },
]
,
status: [
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' },
]
,
birthday: [
{ required: true, message: t('birthdayPlaceholder'), trigger: 'blur' },
]
,
point: [
{ required: true, message: t('pointPlaceholder'), trigger: 'blur' },
]
,
point_get: [
{ required: true, message: t('pointGetPlaceholder'), trigger: 'blur' },
]
,
balance: [
{ required: true, message: t('balancePlaceholder'), trigger: 'blur' },
]
,
balance_get: [
{ required: true, message: t('balanceGetPlaceholder'), trigger: 'blur' },
]
,
money: [
{ required: true, message: t('moneyPlaceholder'), trigger: 'blur' },
]
,
money_get: [
{ required: true, message: t('moneyGetPlaceholder'), trigger: 'blur' },
]
,
money_cash_outing: [
{ required: true, message: t('moneyCashOutingPlaceholder'), trigger: 'blur' },
]
,
growth: [
{ required: true, message: t('growthPlaceholder'), trigger: 'blur' },
]
,
growth_get: [
{ required: true, message: t('growthGetPlaceholder'), trigger: 'blur' },
]
,
commission: [
{ required: true, message: t('commissionPlaceholder'), trigger: 'blur' },
]
,
commission_get: [
{ required: true, message: t('commissionGetPlaceholder'), trigger: 'blur' },
]
,
commission_cash_outing: [
{ required: true, message: t('commissionCashOutingPlaceholder'), trigger: 'blur' },
]
,
is_member: [
{ required: true, message: t('isMemberPlaceholder'), trigger: 'blur' },
]
,
member_time: [
{ required: true, message: t('memberTimePlaceholder'), trigger: 'blur' },
]
,
address: [
{ required: true, message: t('addressPlaceholder'), trigger: 'blur' },
]
,
}
})
const emit = defineEmits(['complete'])
/**
* 确认
* @param formEl
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
let save = formData.member_id ? editUsers : addUsers
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 sexList = ref([])
const sexDictList = async () => {
sexList.value = await (await useDictionary('users_sex')).data.dictionary
}
sexDictList();
watch(() => sexList.value, () => { formData.sex = sexList.value[0].value })
let statusList = ref([])
const statusDictList = async () => {
statusList.value = await (await useDictionary('is_radio')).data.dictionary
}
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
let is_memberList = ref([])
const is_memberDictList = async () => {
is_memberList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_memberDictList();
watch(() => is_memberList.value, () => { formData.is_member = is_memberList.value[0].value })
let is_delList = ref([])
const is_delDictList = async () => {
is_delList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_delDictList();
watch(() => is_delList.value, () => { formData.is_del = is_delList.value[0].value })
const pidList = ref([] as any[])
const setPidList = async () => {
pidList.value = await (await getWithUsersList({})).data
}
setPidList()
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if(row){
const data = await (await getUsersInfo(row.member_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>

481
admin/src/addon/zhjw/views/users/users.vue

@ -0,0 +1,481 @@
<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('addUsers') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="usersTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('username')" prop="username">
<el-input v-model="usersTable.searchParam.username" :placeholder="t('usernamePlaceholder')" />
</el-form-item>
<el-form-item :label="t('mobile')" prop="mobile">
<el-input v-model="usersTable.searchParam.mobile" :placeholder="t('mobilePlaceholder')" />
</el-form-item>
<el-form-item :label="t('nickname')" prop="nickname">
<el-input v-model="usersTable.searchParam.nickname" :placeholder="t('nicknamePlaceholder')" />
</el-form-item>
<el-form-item :label="t('memberLevel')" prop="member_level">
<el-input v-model="usersTable.searchParam.member_level" :placeholder="t('memberLevelPlaceholder')" />
</el-form-item>
<el-form-item :label="t('memberLabel')" prop="member_label">
<el-input v-model="usersTable.searchParam.member_label" :placeholder="t('memberLabelPlaceholder')" />
</el-form-item>
<el-form-item :label="t('wxOpenid')" prop="wx_openid">
<el-input v-model="usersTable.searchParam.wx_openid" :placeholder="t('wxOpenidPlaceholder')" />
</el-form-item>
<el-form-item :label="t('weappOpenid')" prop="weapp_openid">
<el-input v-model="usersTable.searchParam.weapp_openid" :placeholder="t('weappOpenidPlaceholder')" />
</el-form-item>
<el-form-item :label="t('wxUnionid')" prop="wx_unionid">
<el-input v-model="usersTable.searchParam.wx_unionid" :placeholder="t('wxUnionidPlaceholder')" />
</el-form-item>
<el-form-item :label="t('aliOpenid')" prop="ali_openid">
<el-input v-model="usersTable.searchParam.ali_openid" :placeholder="t('aliOpenidPlaceholder')" />
</el-form-item>
<el-form-item :label="t('douyinOpenid')" prop="douyin_openid">
<el-input v-model="usersTable.searchParam.douyin_openid" :placeholder="t('douyinOpenidPlaceholder')" />
</el-form-item>
<el-form-item :label="t('registerChannel')" prop="register_channel">
<el-input v-model="usersTable.searchParam.register_channel" :placeholder="t('registerChannelPlaceholder')" />
</el-form-item>
<el-form-item :label="t('registerType')" prop="register_type">
<el-input v-model="usersTable.searchParam.register_type" :placeholder="t('registerTypePlaceholder')" />
</el-form-item>
<el-form-item :label="t('loginIp')" prop="login_ip">
<el-input v-model="usersTable.searchParam.login_ip" :placeholder="t('loginIpPlaceholder')" />
</el-form-item>
<el-form-item :label="t('loginType')" prop="login_type">
<el-input v-model="usersTable.searchParam.login_type" :placeholder="t('loginTypePlaceholder')" />
</el-form-item>
<el-form-item :label="t('loginChannel')" prop="login_channel">
<el-input v-model="usersTable.searchParam.login_channel" :placeholder="t('loginChannelPlaceholder')" />
</el-form-item>
<el-form-item :label="t('loginCount')" prop="login_count">
<el-input v-model="usersTable.searchParam.login_count" :placeholder="t('loginCountPlaceholder')" />
</el-form-item>
<el-form-item :label="t('loginTime')" prop="login_time">
<el-input v-model="usersTable.searchParam.login_time" :placeholder="t('loginTimePlaceholder')" />
</el-form-item>
<el-form-item :label="t('lastVisitTime')" prop="last_visit_time">
<el-input v-model="usersTable.searchParam.last_visit_time" :placeholder="t('lastVisitTimePlaceholder')" />
</el-form-item>
<el-form-item :label="t('lastConsumTime')" prop="last_consum_time">
<el-input v-model="usersTable.searchParam.last_consum_time" :placeholder="t('lastConsumTimePlaceholder')" />
</el-form-item>
<el-form-item :label="t('sex')" prop="sex">
<el-select class="w-[280px]" v-model="usersTable.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('status')" prop="status">
<el-select class="w-[280px]" v-model="usersTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
: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="usersTable.searchParam.birthday" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item :label="t('point')" prop="point">
<el-input v-model="usersTable.searchParam.point" :placeholder="t('pointPlaceholder')" />
</el-form-item>
<el-form-item :label="t('pointGet')" prop="point_get">
<el-input v-model="usersTable.searchParam.point_get" :placeholder="t('pointGetPlaceholder')" />
</el-form-item>
<el-form-item :label="t('balance')" prop="balance">
<el-input v-model="usersTable.searchParam.balance" :placeholder="t('balancePlaceholder')" />
</el-form-item>
<el-form-item :label="t('balanceGet')" prop="balance_get">
<el-input v-model="usersTable.searchParam.balance_get" :placeholder="t('balanceGetPlaceholder')" />
</el-form-item>
<el-form-item :label="t('money')" prop="money">
<el-input v-model="usersTable.searchParam.money" :placeholder="t('moneyPlaceholder')" />
</el-form-item>
<el-form-item :label="t('moneyGet')" prop="money_get">
<el-input v-model="usersTable.searchParam.money_get" :placeholder="t('moneyGetPlaceholder')" />
</el-form-item>
<el-form-item :label="t('moneyCashOuting')" prop="money_cash_outing">
<el-input v-model="usersTable.searchParam.money_cash_outing" :placeholder="t('moneyCashOutingPlaceholder')" />
</el-form-item>
<el-form-item :label="t('growth')" prop="growth">
<el-input v-model="usersTable.searchParam.growth" :placeholder="t('growthPlaceholder')" />
</el-form-item>
<el-form-item :label="t('growthGet')" prop="growth_get">
<el-input v-model="usersTable.searchParam.growth_get" :placeholder="t('growthGetPlaceholder')" />
</el-form-item>
<el-form-item :label="t('commission')" prop="commission">
<el-input v-model="usersTable.searchParam.commission" :placeholder="t('commissionPlaceholder')" />
</el-form-item>
<el-form-item :label="t('commissionGet')" prop="commission_get">
<el-input v-model="usersTable.searchParam.commission_get" :placeholder="t('commissionGetPlaceholder')" />
</el-form-item>
<el-form-item :label="t('commissionCashOuting')" prop="commission_cash_outing">
<el-input v-model="usersTable.searchParam.commission_cash_outing" :placeholder="t('commissionCashOutingPlaceholder')" />
</el-form-item>
<el-form-item :label="t('isMember')" prop="is_member">
<el-select class="w-[280px]" v-model="usersTable.searchParam.is_member" clearable :placeholder="t('isMemberPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in is_memberList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('memberTime')" prop="member_time">
<el-date-picker v-model="usersTable.searchParam.member_time" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
: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="usersTable.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="loadUsersList()">{{ 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="usersTable.data" size="large" v-loading="usersTable.loading">
<template #empty>
<span>{{ !usersTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="member_id" :label="t('memberId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="member_no" :label="t('memberNo')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="pid_name" :label="t('pid')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="username" :label="t('username')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="mobile" :label="t('mobile')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="password" :label="t('password')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="nickname" :label="t('nickname')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('headimg')" width="100" align="left">
<template #default="{ row }">
<el-avatar v-if="row.headimg" :src="img(row.headimg)" />
<el-avatar v-else icon="UserFilled" />
</template>
</el-table-column>
<el-table-column prop="member_level" :label="t('memberLevel')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="member_label" :label="t('memberLabel')" 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="weapp_openid" :label="t('weappOpenid')" 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 prop="ali_openid" :label="t('aliOpenid')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="douyin_openid" :label="t('douyinOpenid')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="register_channel" :label="t('registerChannel')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="register_type" :label="t('registerType')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="login_ip" :label="t('loginIp')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="login_type" :label="t('loginType')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="login_channel" :label="t('loginChannel')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="login_count" :label="t('loginCount')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="login_time" :label="t('loginTime')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="last_visit_time" :label="t('lastVisitTime')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="last_consum_time" :label="t('lastConsumTime')" 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 :label="t('status')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in statusList">
<div v-if="item.value == row.status">{{ 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 prop="point" :label="t('point')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="point_get" :label="t('pointGet')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="balance" :label="t('balance')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="balance_get" :label="t('balanceGet')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="money" :label="t('money')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="money_get" :label="t('moneyGet')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="money_cash_outing" :label="t('moneyCashOuting')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="growth" :label="t('growth')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="growth_get" :label="t('growthGet')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="commission" :label="t('commission')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="commission_get" :label="t('commissionGet')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="commission_cash_outing" :label="t('commissionCashOuting')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('isMember')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in is_memberList">
<div v-if="item.value == row.is_member">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column :label="t('memberTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.member_time || '' }}
</template>
</el-table-column>
<el-table-column prop="address" :label="t('address')" 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('updateTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.update_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.member_id)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="usersTable.page" v-model:page-size="usersTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="usersTable.total"
@size-change="loadUsersList()" @current-change="loadUsersList" />
</div>
</div>
</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 { getUsersList, deleteUsers, getWithUsersList } from '@/addon/zhjw/api/users'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let usersTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam:{
"username":"",
"mobile":"",
"nickname":"",
"member_level":"",
"member_label":"",
"wx_openid":"",
"weapp_openid":"",
"wx_unionid":"",
"ali_openid":"",
"douyin_openid":"",
"register_channel":"",
"register_type":"",
"login_ip":"",
"login_type":"",
"login_channel":"",
"login_count":"",
"login_time":"",
"last_visit_time":"",
"last_consum_time":"",
"sex":"",
"status":"",
"birthday":[],
"point":"",
"point_get":"",
"balance":"",
"balance_get":"",
"money":"",
"money_get":"",
"money_cash_outing":"",
"growth":"",
"growth_get":"",
"commission":"",
"commission_get":"",
"commission_cash_outing":"",
"is_member":"",
"member_time":[],
"create_time":""
}
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
const sexList = ref([] as any[])
const sexDictList = async () => {
sexList.value = await (await useDictionary('users_sex')).data.dictionary
}
sexDictList();
const statusList = ref([] as any[])
const statusDictList = async () => {
statusList.value = await (await useDictionary('is_radio')).data.dictionary
}
statusDictList();
const is_memberList = ref([] as any[])
const is_memberDictList = async () => {
is_memberList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_memberDictList();
const is_delList = ref([] as any[])
const is_delDictList = async () => {
is_delList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_delDictList();
/**
* 获取用户管理列表
*/
const loadUsersList = (page: number = 1) => {
usersTable.loading = true
usersTable.page = page
getUsersList({
page: usersTable.page,
limit: usersTable.limit,
...usersTable.searchParam
}).then(res => {
usersTable.loading = false
usersTable.data = res.data.data
usersTable.total = res.data.total
}).catch(() => {
usersTable.loading = false
})
}
loadUsersList()
const router = useRouter()
/**
* 添加用户管理
*/
const addEvent = () => {
router.push('/users/users_edit')
}
/**
* 编辑用户管理
* @param data
*/
const editEvent = (data: any) => {
router.push('/users/users_edit?id='+data.member_id)
}
/**
* 删除用户管理
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('usersDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteUsers(id).then(() => {
loadUsersList()
}).catch(() => {
})
})
}
const pidList = ref([])
const setPidList = async () => {
pidList.value = await (await getWithUsersList({})).data
}
setPidList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadUsersList()
}
</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>

612
admin/src/addon/zhjw/views/users/users_edit.vue

@ -0,0 +1,612 @@
<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="90px" ref="formRef" :rules="formRules" class="page-form">
<el-form-item :label="t('memberNo')" >
<el-input v-model="formData.member_no" clearable :placeholder="t('memberNoPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('pid')" >
<el-select class="input-width" v-model="formData.pid" clearable :placeholder="t('pidPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in pidList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('username')" prop="username">
<el-input v-model="formData.username" clearable :placeholder="t('usernamePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('mobile')" prop="mobile">
<el-input v-model="formData.mobile" clearable :placeholder="t('mobilePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('password')" prop="password">
<el-input v-model="formData.password" clearable :placeholder="t('passwordPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('nickname')" prop="nickname">
<el-input v-model="formData.nickname" clearable :placeholder="t('nicknamePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('headimg')">
<upload-image v-model="formData.headimg" />
</el-form-item>
<el-form-item :label="t('memberLevel')" >
<el-input v-model="formData.member_level" clearable :placeholder="t('memberLevelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('memberLabel')" >
<el-input v-model="formData.member_label" clearable :placeholder="t('memberLabelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('wxOpenid')" >
<el-input v-model="formData.wx_openid" clearable :placeholder="t('wxOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('weappOpenid')" >
<el-input v-model="formData.weapp_openid" clearable :placeholder="t('weappOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('wxUnionid')" >
<el-input v-model="formData.wx_unionid" clearable :placeholder="t('wxUnionidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('aliOpenid')" >
<el-input v-model="formData.ali_openid" clearable :placeholder="t('aliOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('douyinOpenid')" >
<el-input v-model="formData.douyin_openid" clearable :placeholder="t('douyinOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('registerChannel')" >
<el-input v-model="formData.register_channel" clearable :placeholder="t('registerChannelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('registerType')" >
<el-input v-model="formData.register_type" clearable :placeholder="t('registerTypePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginIp')" >
<el-input v-model="formData.login_ip" clearable :placeholder="t('loginIpPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginType')" >
<el-input v-model="formData.login_type" clearable :placeholder="t('loginTypePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginChannel')" >
<el-input v-model="formData.login_channel" clearable :placeholder="t('loginChannelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginCount')" >
<el-input v-model="formData.login_count" clearable :placeholder="t('loginCountPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginTime')" >
<el-input v-model="formData.login_time" clearable :placeholder="t('loginTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('lastVisitTime')" >
<el-input v-model="formData.last_visit_time" clearable :placeholder="t('lastVisitTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('lastConsumTime')" >
<el-input v-model="formData.last_consum_time" clearable :placeholder="t('lastConsumTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('sex')" prop="sex">
<el-select class="input-width" v-model="formData.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('status')" prop="status">
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</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="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('birthdayPlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('point')" >
<el-input v-model="formData.point" clearable :placeholder="t('pointPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('pointGet')" >
<el-input v-model="formData.point_get" clearable :placeholder="t('pointGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('balance')" >
<el-input v-model="formData.balance" clearable :placeholder="t('balancePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('balanceGet')" >
<el-input v-model="formData.balance_get" clearable :placeholder="t('balanceGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('money')" >
<el-input v-model="formData.money" clearable :placeholder="t('moneyPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('moneyGet')" >
<el-input v-model="formData.money_get" clearable :placeholder="t('moneyGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('moneyCashOuting')" >
<el-input v-model="formData.money_cash_outing" clearable :placeholder="t('moneyCashOutingPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('growth')" >
<el-input v-model="formData.growth" clearable :placeholder="t('growthPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('growthGet')" >
<el-input v-model="formData.growth_get" clearable :placeholder="t('growthGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commission')" >
<el-input v-model="formData.commission" clearable :placeholder="t('commissionPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commissionGet')" >
<el-input v-model="formData.commission_get" clearable :placeholder="t('commissionGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commissionCashOuting')" >
<el-input v-model="formData.commission_cash_outing" clearable :placeholder="t('commissionCashOutingPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('isMember')" prop="is_member">
<el-select class="input-width" v-model="formData.is_member" clearable :placeholder="t('isMemberPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in is_memberList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('memberTime')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.member_time"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('memberTimePlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('address')" >
<el-input v-model="formData.address" clearable :placeholder="t('addressPlaceholder')" class="input-width" />
</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 { getUsersInfo,addUsers,editUsers, getWithUsersList } from '@/addon/zhjw/api/users';
import { useRoute } from 'vue-router'
const route = useRoute()
const id:number = parseInt(route.query.id);
const loading = ref(false)
const pageName = route.meta.title
/**
* 表单数据
*/
const initialFormData = {
member_id: 0,
member_no: '',
pid: '',
username: '',
mobile: '',
password: '',
nickname: '',
headimg: '',
member_level: 0,
member_label: '',
wx_openid: '',
weapp_openid: '',
wx_unionid: '',
ali_openid: '',
douyin_openid: '',
register_channel: '',
register_type: '',
login_ip: '',
login_type: '',
login_channel: '',
login_count: 0,
login_time: 0,
last_visit_time: 0,
last_consum_time: 0,
sex: 0,
status: 0,
birthday: '',
point: 0,
point_get: 0,
balance: '',
balance_get: '',
money: '',
money_get: '',
money_cash_outing: '',
growth: 0,
growth_get: 0,
commission: '',
commission_get: '',
commission_cash_outing: '',
is_member: 0,
member_time: 0,
address: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const setFormData = async (id:number = 0) => {
Object.assign(formData, initialFormData)
const data = await (await getUsersInfo(id)).data
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
if(id) setFormData(id);
const formRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
let sexList = ref([])
const sexDictList = async () => {
sexList.value = await (await useDictionary('users_sex')).data.dictionary
}
sexDictList();
watch(() => sexList.value, () => { formData.sex = sexList.value[0].value })
let statusList = ref([])
const statusDictList = async () => {
statusList.value = await (await useDictionary('is_radio')).data.dictionary
}
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
let is_memberList = ref([])
const is_memberDictList = async () => {
is_memberList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_memberDictList();
watch(() => is_memberList.value, () => { formData.is_member = is_memberList.value[0].value })
let is_delList = ref([])
const is_delDictList = async () => {
is_delList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_delDictList();
watch(() => is_delList.value, () => { formData.is_del = is_delList.value[0].value })
const pidList = ref([] as any[])
const setPidList = async () => {
pidList.value = await (await getWithUsersList({})).data
}
setPidList()
//
const formRules = computed(() => {
return {
member_no: [
{ required: true, message: t('memberNoPlaceholder'), trigger: 'blur' },
]
,
pid: [
{ required: true, message: t('pidPlaceholder'), trigger: 'blur' },
]
,
username: [
{ required: true, message: t('usernamePlaceholder'), trigger: 'blur' },
]
,
mobile: [
{ required: true, message: t('mobilePlaceholder'), trigger: 'blur' },
]
,
password: [
{ required: true, message: t('passwordPlaceholder'), trigger: 'blur' },
]
,
nickname: [
{ required: true, message: t('nicknamePlaceholder'), trigger: 'blur' },
]
,
headimg: [
{ required: true, message: t('headimgPlaceholder'), trigger: 'blur' },
]
,
member_level: [
{ required: true, message: t('memberLevelPlaceholder'), trigger: 'blur' },
]
,
member_label: [
{ required: true, message: t('memberLabelPlaceholder'), trigger: 'blur' },
]
,
wx_openid: [
{ required: true, message: t('wxOpenidPlaceholder'), trigger: 'blur' },
]
,
weapp_openid: [
{ required: true, message: t('weappOpenidPlaceholder'), trigger: 'blur' },
]
,
wx_unionid: [
{ required: true, message: t('wxUnionidPlaceholder'), trigger: 'blur' },
]
,
ali_openid: [
{ required: true, message: t('aliOpenidPlaceholder'), trigger: 'blur' },
]
,
douyin_openid: [
{ required: true, message: t('douyinOpenidPlaceholder'), trigger: 'blur' },
]
,
register_channel: [
{ required: true, message: t('registerChannelPlaceholder'), trigger: 'blur' },
]
,
register_type: [
{ required: true, message: t('registerTypePlaceholder'), trigger: 'blur' },
]
,
login_ip: [
{ required: true, message: t('loginIpPlaceholder'), trigger: 'blur' },
]
,
login_type: [
{ required: true, message: t('loginTypePlaceholder'), trigger: 'blur' },
]
,
login_channel: [
{ required: true, message: t('loginChannelPlaceholder'), trigger: 'blur' },
]
,
login_count: [
{ required: true, message: t('loginCountPlaceholder'), trigger: 'blur' },
]
,
login_time: [
{ required: true, message: t('loginTimePlaceholder'), trigger: 'blur' },
]
,
last_visit_time: [
{ required: true, message: t('lastVisitTimePlaceholder'), trigger: 'blur' },
]
,
last_consum_time: [
{ required: true, message: t('lastConsumTimePlaceholder'), trigger: 'blur' },
]
,
sex: [
{ required: true, message: t('sexPlaceholder'), trigger: 'blur' },
]
,
status: [
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' },
]
,
birthday: [
{ required: true, message: t('birthdayPlaceholder'), trigger: 'blur' },
]
,
point: [
{ required: true, message: t('pointPlaceholder'), trigger: 'blur' },
]
,
point_get: [
{ required: true, message: t('pointGetPlaceholder'), trigger: 'blur' },
]
,
balance: [
{ required: true, message: t('balancePlaceholder'), trigger: 'blur' },
]
,
balance_get: [
{ required: true, message: t('balanceGetPlaceholder'), trigger: 'blur' },
]
,
money: [
{ required: true, message: t('moneyPlaceholder'), trigger: 'blur' },
]
,
money_get: [
{ required: true, message: t('moneyGetPlaceholder'), trigger: 'blur' },
]
,
money_cash_outing: [
{ required: true, message: t('moneyCashOutingPlaceholder'), trigger: 'blur' },
]
,
growth: [
{ required: true, message: t('growthPlaceholder'), trigger: 'blur' },
]
,
growth_get: [
{ required: true, message: t('growthGetPlaceholder'), trigger: 'blur' },
]
,
commission: [
{ required: true, message: t('commissionPlaceholder'), trigger: 'blur' },
]
,
commission_get: [
{ required: true, message: t('commissionGetPlaceholder'), trigger: 'blur' },
]
,
commission_cash_outing: [
{ required: true, message: t('commissionCashOutingPlaceholder'), trigger: 'blur' },
]
,
is_member: [
{ required: true, message: t('isMemberPlaceholder'), trigger: 'blur' },
]
,
member_time: [
{ required: true, message: t('memberTimePlaceholder'), trigger: 'blur' },
]
,
address: [
{ required: true, message: t('addressPlaceholder'), 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 = id ? editUsers : addUsers
save(data).then(res => {
loading.value = false
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()
}
</script>
<style lang="scss" scoped></style>

2
niucloud/.env

@ -1 +1 @@
APP_DEBUG = true [APP] DEFAULT_TIMEZONE = Asia/Shanghai AUTH_KEY = ymektwfaxgsdigfpbnjoruhczasdvhql PRODUCT_KEY = {product_key} [DATABASE] TYPE = mysql HOSTNAME = 127.0.0.1 DATABASE = school_oa USERNAME = root PASSWORD = root HOSTPORT = 3306 PREFIX = school_ CHARSET = utf8mb4 DEBUG = false [REDIS] REDIS_HOSTNAME = 127.0.0.1 PORT = 6379 REDIS_PASSWORD = SELECT = 0 [QUEUE] state = false [LANG] default_lang = zh-cn [SYSTEM] ADMIN_TOKEN_NAME = token API_TOKEN_NAME = token ADMIN_TOKEN_EXPIRE_TIME = 604800 API_TOKEN_EXPIRE_TIME = 86400 LANG_NAME = lang CHANNEL_NAME = channel ADMIN_DOMAIN = WAP_DOMAIN = WEB_DOMAIN = [NIUCLOUD] code = secret =
APP_DEBUG = true [APP] DEFAULT_TIMEZONE = Asia/Shanghai AUTH_KEY = ymektwfaxgsdigfpbnjoruhczasdvhql PRODUCT_KEY = {product_key} [DATABASE] TYPE = mysql HOSTNAME = 146.56.228.75 DATABASE = school_oa USERNAME = school_oa PASSWORD = xseii2aBWjmSSBpB HOSTPORT = 3306 PREFIX = school_ CHARSET = utf8mb4 DEBUG = false [REDIS] REDIS_HOSTNAME = 127.0.0.1 PORT = 6379 REDIS_PASSWORD = SELECT = 0 [QUEUE] state = false [LANG] default_lang = zh-cn [SYSTEM] ADMIN_TOKEN_NAME = token API_TOKEN_NAME = token ADMIN_TOKEN_EXPIRE_TIME = 604800 API_TOKEN_EXPIRE_TIME = 86400 LANG_NAME = lang CHANNEL_NAME = channel ADMIN_DOMAIN = WAP_DOMAIN = WEB_DOMAIN = [NIUCLOUD] code = secret =

6
niucloud/addon/zhjw/admin/api/articles.ts

@ -1,5 +1,11 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- zhjw_articles
/**
*

62
niucloud/addon/zhjw/admin/api/contracts.ts

@ -0,0 +1,62 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- zhjw_contracts
/**
*
* @param params
* @returns
*/
export function getContractsList(params: Record<string, any>) {
return request.get(`zhjw/contracts`, {params})
}
/**
*
* @param id id
* @returns
*/
export function getContractsInfo(id: number) {
return request.get(`zhjw/contracts/${id}`);
}
/**
*
* @param params
* @returns
*/
export function addContracts(params: Record<string, any>) {
return request.post('zhjw/contracts', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @param params
* @returns
*/
export function editContracts(params: Record<string, any>) {
return request.put(`zhjw/contracts/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @returns
*/
export function deleteContracts(id: number) {
return request.delete(`zhjw/contracts/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithUsersList(params: Record<string,any>){
return request.get('zhjw/users_all', {params})
}
// USER_CODE_END -- zhjw_contracts

56
niucloud/addon/zhjw/admin/api/orders.ts

@ -0,0 +1,56 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- zhjw_orders
/**
* -
* @param params
* @returns
*/
export function getOrdersList(params: Record<string, any>) {
return request.get(`zhjw/orders`, {params})
}
/**
* -
* @param id -id
* @returns
*/
export function getOrdersInfo(id: number) {
return request.get(`zhjw/orders/${id}`);
}
/**
* -
* @param params
* @returns
*/
export function addOrders(params: Record<string, any>) {
return request.post('zhjw/orders', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* -
* @param id
* @param params
* @returns
*/
export function editOrders(params: Record<string, any>) {
return request.put(`zhjw/orders/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
* -
* @param id
* @returns
*/
export function deleteOrders(id: number) {
return request.delete(`zhjw/orders/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithMemberList(params: Record<string,any>){
return request.get('zhjw/member_all', {params})
}export function getWithContractsList(params: Record<string,any>){
return request.get('zhjw/contracts_all', {params})
}
// USER_CODE_END -- zhjw_orders

58
niucloud/addon/zhjw/admin/api/students.ts

@ -0,0 +1,58 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- zhjw_students
/**
*
* @param params
* @returns
*/
export function getStudentsList(params: Record<string, any>) {
return request.get(`zhjw/students`, {params})
}
/**
*
* @param id id
* @returns
*/
export function getStudentsInfo(id: number) {
return request.get(`zhjw/students/${id}`);
}
/**
*
* @param params
* @returns
*/
export function addStudents(params: Record<string, any>) {
return request.post('zhjw/students', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @param params
* @returns
*/
export function editStudents(params: Record<string, any>) {
return request.put(`zhjw/students/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @returns
*/
export function deleteStudents(id: number) {
return request.delete(`zhjw/students/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithUsersList(params: Record<string,any>){
return request.get('zhjw/users_all', {params})
}
// USER_CODE_END -- zhjw_students

62
niucloud/addon/zhjw/admin/api/users.ts

@ -0,0 +1,62 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- zhjw_users
/**
*
* @param params
* @returns
*/
export function getUsersList(params: Record<string, any>) {
return request.get(`zhjw/users`, {params})
}
/**
*
* @param member_id member_id
* @returns
*/
export function getUsersInfo(member_id: number) {
return request.get(`zhjw/users/${member_id}`);
}
/**
*
* @param params
* @returns
*/
export function addUsers(params: Record<string, any>) {
return request.post('zhjw/users', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param member_id
* @param params
* @returns
*/
export function editUsers(params: Record<string, any>) {
return request.put(`zhjw/users/${params.member_id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param member_id
* @returns
*/
export function deleteUsers(member_id: number) {
return request.delete(`zhjw/users/${member_id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithUsersList(params: Record<string,any>){
return request.get('zhjw/users_all', {params})
}
// USER_CODE_END -- zhjw_users

7
niucloud/addon/zhjw/admin/lang/zh-cn/articles.articles.json

@ -1,14 +1,17 @@
{
"id":"序号",
"title":"标题",
"titlePlaceholder":"请输入标题",
"content":"内容",
"contentPlaceholder":"请输入内容",
"category":"文章分类",
"categoryPlaceholder":"请输入文章分类",
"publisherId":"发布人",
"publisherIdPlaceholder":"全部",
"status":"状态",
"statusPlaceholder":"请输入状态",
"createTime":"添加时间",
"createTimePlaceholder":"请输入添加时间",
"updateTime":"更新时间",
"updateTimePlaceholder":"请输入更新时间",
"addArticles":"添加文章管理",
"updateArticles":"编辑文章管理",
"articlesDeleteTips":"确定要删除该数据吗?",

2
niucloud/addon/zhjw/admin/lang/zh-cn/articles.articles_edit.json

@ -8,7 +8,7 @@
"contentPlaceholder":"请输入内容",
"categoryPlaceholder":"请选择文章分类",
"publisherIdPlaceholder":"请选择发布人",
"statusPlaceholder":"请输入状态",
"statusPlaceholder":"请选择状态",
"addArticles":"添加文章管理",
"updateArticles":"编辑文章管理",
"articlesDeleteTips":"确定要删除该文章管理吗?"

21
niucloud/addon/zhjw/admin/lang/zh-cn/contracts.contracts.json

@ -0,0 +1,21 @@
{
"id":"序号",
"studentId":"学员",
"studentIdPlaceholder":"全部",
"title":"合同名称",
"titlePlaceholder":"请输入合同名称",
"startDate":"生效日期",
"startDatePlaceholder":"请输入生效日期",
"endDate":"终止日期",
"endDatePlaceholder":"请输入终止日期",
"status":"状态",
"statusPlaceholder":"请输入状态",
"createTime":"添加时间",
"createTimePlaceholder":"请输入添加时间",
"updateTime":"更新时间",
"addContracts":"添加合同管理",
"updateContracts":"编辑合同管理",
"contractsDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

19
niucloud/addon/zhjw/admin/lang/zh-cn/contracts.contracts_edit.json

@ -0,0 +1,19 @@
{
"studentId":"学员",
"title":"合同名称",
"content":"合同内容",
"fileData":"合同文件路径",
"startDate":"生效日期",
"endDate":"终止日期",
"status":"状态",
"studentIdPlaceholder":"请选择学员",
"titlePlaceholder":"请输入合同名称",
"contentPlaceholder":"请输入合同内容",
"fileDataPlaceholder":"请输入合同文件路径",
"startDatePlaceholder":"请选择生效日期",
"endDatePlaceholder":"请选择终止日期",
"statusPlaceholder":"请选择状态",
"addContracts":"添加合同管理",
"updateContracts":"编辑合同管理",
"contractsDeleteTips":"确定要删除该合同管理吗?"
}

26
niucloud/addon/zhjw/admin/lang/zh-cn/orders.orders.json

@ -0,0 +1,26 @@
{
"id":"序号",
"studentId":"学员",
"studentIdPlaceholder":"全部",
"contractId":"关联合同",
"contractIdPlaceholder":"全部",
"amount":"订单金额",
"amountPlaceholder":"请输入订单金额",
"orderType":"订单类型",
"orderTypePlaceholder":"请输入订单类型",
"payType":"支付类型",
"payTypePlaceholder":"请输入支付类型",
"paymentStatus":"支付状态",
"paymentStatusPlaceholder":"请输入支付状态",
"paymentTime":"支付时间",
"paymentTimePlaceholder":"请输入支付时间",
"createTime":"添加时间",
"createTimePlaceholder":"请输入添加时间",
"updateTime":"更新时间",
"isDeleted":"是否删除",
"addOrders":"添加智慧教务-订单管理",
"updateOrders":"编辑智慧教务-订单管理",
"ordersDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

19
niucloud/addon/zhjw/admin/lang/zh-cn/orders.orders_edit.json

@ -0,0 +1,19 @@
{
"studentId":"学员",
"contractId":"关联合同",
"amount":"订单金额",
"orderType":"订单类型",
"payType":"支付类型",
"paymentStatus":"支付状态",
"paymentTime":"支付时间",
"studentIdPlaceholder":"请选择学员",
"contractIdPlaceholder":"请选择关联合同",
"amountPlaceholder":"请输入订单金额",
"orderTypePlaceholder":"请选择订单类型",
"payTypePlaceholder":"请选择支付类型",
"paymentStatusPlaceholder":"请选择支付状态",
"paymentTimePlaceholder":"请选择支付时间",
"addOrders":"添加智慧教务-订单管理",
"updateOrders":"编辑智慧教务-订单管理",
"ordersDeleteTips":"确定要删除该智慧教务-订单管理吗?"
}

25
niucloud/addon/zhjw/admin/lang/zh-cn/students.students.json

@ -0,0 +1,25 @@
{
"id":"序号",
"name":"姓名",
"namePlaceholder":"请输入姓名",
"userId":"关联用户",
"userIdPlaceholder":"全部",
"haveStudyTime":"学员有效学时",
"haveStudyTimePlaceholder":"请输入学员有效学时",
"endStudyTime":"学员完成学时",
"endStudyTimePlaceholder":"请输入学员完成学时",
"emergencyContact":"紧急联系人",
"emergencyContactPlaceholder":"请输入紧急联系人",
"level":"学员等级",
"levelPlaceholder":"请输入学员等级",
"status":"状态",
"statusPlaceholder":"请输入状态",
"createTime":"添加时间",
"createTimePlaceholder":"请输入添加时间",
"updateTime":"更新时间",
"addStudents":"添加学员管理",
"updateStudents":"编辑学员管理",
"studentsDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

19
niucloud/addon/zhjw/admin/lang/zh-cn/students.students_edit.json

@ -0,0 +1,19 @@
{
"name":"姓名",
"userId":"关联用户",
"haveStudyTime":"学员有效学时",
"endStudyTime":"学员完成学时",
"emergencyContact":"紧急联系人",
"level":"学员等级",
"status":"状态",
"namePlaceholder":"请输入姓名",
"userIdPlaceholder":"请选择关联用户",
"haveStudyTimePlaceholder":"请输入学员有效学时",
"endStudyTimePlaceholder":"请输入学员完成学时",
"emergencyContactPlaceholder":"请输入紧急联系人",
"levelPlaceholder":"请输入学员等级",
"statusPlaceholder":"请选择状态",
"addStudents":"添加学员管理",
"updateStudents":"编辑学员管理",
"studentsDeleteTips":"确定要删除该学员管理吗?"
}

88
niucloud/addon/zhjw/admin/lang/zh-cn/users.users.json

@ -0,0 +1,88 @@
{
"memberId":"序号",
"memberNo":"会员编码",
"pid":"推广会员",
"username":"会员用户名",
"usernamePlaceholder":"请输入会员用户名",
"mobile":"手机号",
"mobilePlaceholder":"请输入手机号",
"password":"会员密码",
"nickname":"会员昵称",
"nicknamePlaceholder":"请输入会员昵称",
"headimg":"会员头像",
"memberLevel":"会员等级",
"memberLevelPlaceholder":"请输入会员等级",
"memberLabel":"会员标签",
"memberLabelPlaceholder":"请输入会员标签",
"wxOpenid":"微信用户openid",
"wxOpenidPlaceholder":"请输入微信用户openid",
"weappOpenid":"微信小程序openid",
"weappOpenidPlaceholder":"请输入微信小程序openid",
"wxUnionid":"微信unionid",
"wxUnionidPlaceholder":"请输入微信unionid",
"aliOpenid":"支付宝账户id",
"aliOpenidPlaceholder":"请输入支付宝账户id",
"douyinOpenid":"抖音小程序openid",
"douyinOpenidPlaceholder":"请输入抖音小程序openid",
"registerChannel":"注册来源",
"registerChannelPlaceholder":"请输入注册来源",
"registerType":"注册方式",
"registerTypePlaceholder":"请输入注册方式",
"loginIp":"当前登录ip",
"loginIpPlaceholder":"请输入当前登录ip",
"loginType":"当前登录的操作终端类型",
"loginTypePlaceholder":"请输入当前登录的操作终端类型",
"loginChannel":"登录渠道",
"loginChannelPlaceholder":"请输入登录渠道",
"loginCount":"登录次数",
"loginCountPlaceholder":"请输入登录次数",
"loginTime":"当前登录时间",
"loginTimePlaceholder":"请输入当前登录时间",
"lastVisitTime":"最后访问时间",
"lastVisitTimePlaceholder":"请输入最后访问时间",
"lastConsumTime":"最后消费时间",
"lastConsumTimePlaceholder":"请输入最后消费时间",
"sex":"性别",
"sexPlaceholder":"请输入性别",
"status":"用户状态",
"statusPlaceholder":"请输入用户状态",
"birthday":"出生日期",
"birthdayPlaceholder":"请输入出生日期",
"point":"可用积分",
"pointPlaceholder":"请输入可用积分",
"pointGet":"累计获取积分",
"pointGetPlaceholder":"请输入累计获取积分",
"balance":"可用余额",
"balancePlaceholder":"请输入可用余额",
"balanceGet":"累计获取余额",
"balanceGetPlaceholder":"请输入累计获取余额",
"money":"可用余额(可提现)",
"moneyPlaceholder":"请输入可用余额(可提现)",
"moneyGet":"累计获取余额(可提现)",
"moneyGetPlaceholder":"请输入累计获取余额(可提现)",
"moneyCashOuting":"提现中余额(可提现)",
"moneyCashOutingPlaceholder":"请输入提现中余额(可提现)",
"growth":"成长值",
"growthPlaceholder":"请输入成长值",
"growthGet":"累计获得成长值",
"growthGetPlaceholder":"请输入累计获得成长值",
"commission":"当前佣金",
"commissionPlaceholder":"请输入当前佣金",
"commissionGet":"佣金获取",
"commissionGetPlaceholder":"请输入佣金获取",
"commissionCashOuting":"提现中佣金",
"commissionCashOutingPlaceholder":"请输入提现中佣金",
"isMember":"是否是会员",
"isMemberPlaceholder":"请输入是否是会员",
"memberTime":"成为会员时间",
"memberTimePlaceholder":"请输入成为会员时间",
"address":"详细地址",
"createTime":"注册时间",
"createTimePlaceholder":"请输入注册时间",
"updateTime":"修改时间",
"addUsers":"添加用户管理",
"updateUsers":"编辑用户管理",
"usersDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

87
niucloud/addon/zhjw/admin/lang/zh-cn/users.users_edit.json

@ -0,0 +1,87 @@
{
"memberNo":"会员编码",
"pid":"推广会员",
"username":"会员用户名",
"mobile":"手机号",
"password":"会员密码",
"nickname":"会员昵称",
"headimg":"会员头像",
"memberLevel":"会员等级",
"memberLabel":"会员标签",
"wxOpenid":"微信用户openid",
"weappOpenid":"微信小程序openid",
"wxUnionid":"微信unionid",
"aliOpenid":"支付宝账户id",
"douyinOpenid":"抖音小程序openid",
"registerChannel":"注册来源",
"registerType":"注册方式",
"loginIp":"当前登录ip",
"loginType":"当前登录的操作终端类型",
"loginChannel":"登录渠道",
"loginCount":"登录次数",
"loginTime":"当前登录时间",
"lastVisitTime":"最后访问时间",
"lastConsumTime":"最后消费时间",
"sex":"性别",
"status":"用户状态",
"birthday":"出生日期",
"point":"可用积分",
"pointGet":"累计获取积分",
"balance":"可用余额",
"balanceGet":"累计获取余额",
"money":"可用余额(可提现)",
"moneyGet":"累计获取余额(可提现)",
"moneyCashOuting":"提现中余额(可提现)",
"growth":"成长值",
"growthGet":"累计获得成长值",
"commission":"当前佣金",
"commissionGet":"佣金获取",
"commissionCashOuting":"提现中佣金",
"isMember":"是否是会员",
"memberTime":"成为会员时间",
"address":"详细地址",
"memberNoPlaceholder":"请输入会员编码",
"pidPlaceholder":"请选择推广会员",
"usernamePlaceholder":"请输入会员用户名",
"mobilePlaceholder":"请输入手机号",
"passwordPlaceholder":"请输入会员密码",
"nicknamePlaceholder":"请输入会员昵称",
"headimgPlaceholder":"请上传会员头像",
"memberLevelPlaceholder":"请输入会员等级",
"memberLabelPlaceholder":"请输入会员标签",
"wxOpenidPlaceholder":"请输入微信用户openid",
"weappOpenidPlaceholder":"请输入微信小程序openid",
"wxUnionidPlaceholder":"请输入微信unionid",
"aliOpenidPlaceholder":"请输入支付宝账户id",
"douyinOpenidPlaceholder":"请输入抖音小程序openid",
"registerChannelPlaceholder":"请输入注册来源",
"registerTypePlaceholder":"请输入注册方式",
"loginIpPlaceholder":"请输入当前登录ip",
"loginTypePlaceholder":"请输入当前登录的操作终端类型",
"loginChannelPlaceholder":"请输入登录渠道",
"loginCountPlaceholder":"请输入登录次数",
"loginTimePlaceholder":"请输入当前登录时间",
"lastVisitTimePlaceholder":"请输入最后访问时间",
"lastConsumTimePlaceholder":"请输入最后消费时间",
"sexPlaceholder":"请选择性别",
"statusPlaceholder":"请选择用户状态",
"birthdayPlaceholder":"请选择出生日期",
"pointPlaceholder":"请输入可用积分",
"pointGetPlaceholder":"请输入累计获取积分",
"balancePlaceholder":"请输入可用余额",
"balanceGetPlaceholder":"请输入累计获取余额",
"moneyPlaceholder":"请输入可用余额(可提现)",
"moneyGetPlaceholder":"请输入累计获取余额(可提现)",
"moneyCashOutingPlaceholder":"请输入提现中余额(可提现)",
"growthPlaceholder":"请输入成长值",
"growthGetPlaceholder":"请输入累计获得成长值",
"commissionPlaceholder":"请输入当前佣金",
"commissionGetPlaceholder":"请输入佣金获取",
"commissionCashOutingPlaceholder":"请输入提现中佣金",
"isMemberPlaceholder":"请选择是否是会员",
"memberTimePlaceholder":"请选择成为会员时间",
"addressPlaceholder":"请输入详细地址",
"addUsers":"添加用户管理",
"updateUsers":"编辑用户管理",
"usersDeleteTips":"确定要删除该用户管理吗?"
}

43
niucloud/addon/zhjw/admin/views/articles/articles.vue

@ -14,9 +14,6 @@
<el-form-item :label="t('title')" prop="title">
<el-input v-model="articlesTable.searchParam.title" :placeholder="t('titlePlaceholder')" />
</el-form-item>
<el-form-item :label="t('content')" prop="content">
<el-input v-model="articlesTable.searchParam.content" :placeholder="t('contentPlaceholder')" />
</el-form-item>
<el-form-item :label="t('category')" prop="category">
<el-select class="w-[280px]" v-model="articlesTable.searchParam.category" clearable :placeholder="t('categoryPlaceholder')">
@ -36,8 +33,8 @@
<el-option
v-for="(item, index) in publisherIdList"
:key="index"
:label="item['uid']"
:value="item['real_name']"
:label="item['username']"
:value="item['uid']"
/>
</el-select>
</el-form-item>
@ -54,6 +51,16 @@
/>
</el-select>
</el-form-item>
<el-form-item :label="t('createTime')" prop="create_time">
<el-date-picker v-model="articlesTable.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 :label="t('updateTime')" prop="update_time">
<el-date-picker v-model="articlesTable.searchParam.update_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="loadArticlesList()">{{ t('search') }}</el-button>
@ -67,6 +74,8 @@
<template #empty>
<span>{{ !articlesTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="title" :label="t('title')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('category')" min-width="180" align="center" :show-overflow-tooltip="true">
@ -86,6 +95,18 @@
</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('updateTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.update_time || '' }}
</template>
</el-table-column>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
@ -127,10 +148,11 @@ let articlesTable = reactive({
data: [],
searchParam:{
"title":"",
"content":"",
"category":"",
"publisher_id":"",
"status":""
"status":"",
"create_time":[],
"update_time":[]
}
})
@ -149,7 +171,12 @@ const selectData = ref<any[]>([])
const statusDictList = async () => {
statusList.value = await (await useDictionary('is_radio')).data.dictionary
}
statusDictList();
statusDictList();
const is_deletedList = ref([] as any[])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
/**
* 获取文章管理列表

31
niucloud/addon/zhjw/admin/views/articles/articles_edit.vue

@ -14,10 +14,9 @@
<el-input v-model="formData.title" clearable :placeholder="t('titlePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('content')" prop="content">
<el-input v-model="formData.content" clearable :placeholder="t('contentPlaceholder')" class="input-width" />
<el-form-item :label="t('content')" >
<editor v-model="formData.content" />
</el-form-item>
<el-form-item :label="t('category')" prop="category">
<el-select class="input-width" v-model="formData.category" clearable :placeholder="t('categoryPlaceholder')">
<el-option label="请选择" value=""></el-option>
@ -36,20 +35,22 @@
<el-option
v-for="(item, index) in publisherIdList"
:key="index"
:label="item['uid']"
:value="item['real_name']"
:label="item['username']"
:value="item['uid']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-radio-group v-model="formData.status" :placeholder="t('statusPlaceholder')">
<el-radio
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index" :label="item.value">
{{ item.name }}
</el-radio>
</el-radio-group>
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
@ -116,7 +117,13 @@ const selectData = ref<any[]>([])
statusList.value = await (await useDictionary('is_radio')).data.dictionary
}
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
let is_deletedList = ref([])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
watch(() => is_deletedList.value, () => { formData.is_deleted = is_deletedList.value[0].value })
const publisherIdList = ref([] as any[])

244
niucloud/addon/zhjw/admin/views/contracts/contracts.vue

@ -0,0 +1,244 @@
<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('addContracts') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="contractsTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('studentId')" prop="student_id">
<el-select class="w-[280px]" v-model="contractsTable.searchParam.student_id" clearable :placeholder="t('studentIdPlaceholder')">
<el-option
v-for="(item, index) in studentIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('title')" prop="title">
<el-input v-model="contractsTable.searchParam.title" :placeholder="t('titlePlaceholder')" />
</el-form-item>
<el-form-item :label="t('startDate')" prop="start_date">
<el-date-picker v-model="contractsTable.searchParam.start_date" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item :label="t('endDate')" prop="end_date">
<el-date-picker v-model="contractsTable.searchParam.end_date" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-select class="w-[280px]" v-model="contractsTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
: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="contractsTable.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="loadContractsList()">{{ 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="contractsTable.data" size="large" v-loading="contractsTable.loading">
<template #empty>
<span>{{ !contractsTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="student_id_name" :label="t('studentId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="title" :label="t('title')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="start_date" :label="t('startDate')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="end_date" :label="t('endDate')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('status')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in statusList">
<div v-if="item.value == row.status">{{ 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('updateTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.update_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="contractsTable.page" v-model:page-size="contractsTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="contractsTable.total"
@size-change="loadContractsList()" @current-change="loadContractsList" />
</div>
</div>
</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 { getContractsList, deleteContracts, getWithUsersList } from '@/addon/zhjw/api/contracts'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let contractsTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam:{
"student_id":"",
"title":"",
"start_date":[],
"end_date":[],
"status":"",
"create_time":[]
}
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
const statusList = ref([] as any[])
const statusDictList = async () => {
statusList.value = await (await useDictionary('zhjw_contracts_status')).data.dictionary
}
statusDictList();
const is_deletedList = ref([] as any[])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
/**
* 获取合同管理列表
*/
const loadContractsList = (page: number = 1) => {
contractsTable.loading = true
contractsTable.page = page
getContractsList({
page: contractsTable.page,
limit: contractsTable.limit,
...contractsTable.searchParam
}).then(res => {
contractsTable.loading = false
contractsTable.data = res.data.data
contractsTable.total = res.data.total
}).catch(() => {
contractsTable.loading = false
})
}
loadContractsList()
const router = useRouter()
/**
* 添加合同管理
*/
const addEvent = () => {
router.push('/contracts/contracts_edit')
}
/**
* 编辑合同管理
* @param data
*/
const editEvent = (data: any) => {
router.push('/contracts/contracts_edit?id='+data.id)
}
/**
* 删除合同管理
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('contractsDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteContracts(id).then(() => {
loadContractsList()
}).catch(() => {
})
})
}
const studentIdList = ref([])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithUsersList({})).data
}
setStudentIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadContractsList()
}
</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>

243
niucloud/addon/zhjw/admin/views/contracts/contracts_edit.vue

@ -0,0 +1,243 @@
<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="90px" ref="formRef" :rules="formRules" class="page-form">
<el-form-item :label="t('studentId')" prop="student_id">
<el-select class="input-width" v-model="formData.student_id" clearable :placeholder="t('studentIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in studentIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('title')" prop="title">
<el-input v-model="formData.title" clearable :placeholder="t('titlePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('content')" >
<editor v-model="formData.content" />
</el-form-item>
<el-form-item :label="t('fileData')">
<upload-file v-model="formData.file_data" />
</el-form-item>
<el-form-item :label="t('startDate')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.start_date"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('startDatePlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('endDate')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.end_date"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('endDatePlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('status')" >
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</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 { getContractsInfo,addContracts,editContracts, getWithUsersList } from '@/addon/zhjw/api/contracts';
import { useRoute } from 'vue-router'
const route = useRoute()
const id:number = parseInt(route.query.id);
const loading = ref(false)
const pageName = route.meta.title
/**
* 表单数据
*/
const initialFormData = {
id: 0,
student_id: '',
title: '',
content: '',
file_data: '',
start_date: '',
end_date: '',
status: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const setFormData = async (id:number = 0) => {
Object.assign(formData, initialFormData)
const data = await (await getContractsInfo(id)).data
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
if(id) setFormData(id);
const formRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
let statusList = ref([])
const statusDictList = async () => {
statusList.value = await (await useDictionary('zhjw_contracts_status')).data.dictionary
}
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
let is_deletedList = ref([])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
watch(() => is_deletedList.value, () => { formData.is_deleted = is_deletedList.value[0].value })
const studentIdList = ref([] as any[])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithUsersList({})).data
}
setStudentIdList()
//
const formRules = computed(() => {
return {
student_id: [
{ required: true, message: t('studentIdPlaceholder'), trigger: 'blur' },
]
,
title: [
{ required: true, message: t('titlePlaceholder'), trigger: 'blur' },
]
,
content: [
{ required: true, message: t('contentPlaceholder'), trigger: 'blur' },
]
,
file_data: [
{ required: true, message: t('fileDataPlaceholder'), trigger: 'blur' },
]
,
start_date: [
{ required: true, message: t('startDatePlaceholder'), trigger: 'blur' },
]
,
end_date: [
{ required: true, message: t('endDatePlaceholder'), trigger: 'blur' },
]
,
status: [
{ required: true, message: t('statusPlaceholder'), 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 = id ? editContracts : addContracts
save(data).then(res => {
loading.value = false
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()
}
</script>
<style lang="scss" scoped></style>

323
niucloud/addon/zhjw/admin/views/orders/orders.vue

@ -0,0 +1,323 @@
<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('addOrders') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="ordersTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('studentId')" prop="student_id">
<el-select class="w-[280px]" v-model="ordersTable.searchParam.student_id" clearable :placeholder="t('studentIdPlaceholder')">
<el-option
v-for="(item, index) in studentIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('contractId')" prop="contract_id">
<el-select class="w-[280px]" v-model="ordersTable.searchParam.contract_id" clearable :placeholder="t('contractIdPlaceholder')">
<el-option
v-for="(item, index) in contractIdList"
:key="index"
:label="item['title']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('amount')" prop="amount">
<range-input v-model="ordersTable.searchParam.amount"/>
</el-form-item>
<el-form-item :label="t('orderType')" prop="order_type">
<el-select class="w-[280px]" v-model="ordersTable.searchParam.order_type" clearable :placeholder="t('orderTypePlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in order_typeList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('payType')" prop="pay_type">
<el-select class="w-[280px]" v-model="ordersTable.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('paymentStatus')" prop="payment_status">
<el-select class="w-[280px]" v-model="ordersTable.searchParam.payment_status" clearable :placeholder="t('paymentStatusPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in payment_statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('paymentTime')" prop="payment_time">
<el-date-picker v-model="ordersTable.searchParam.payment_time" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
: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="ordersTable.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="loadOrdersList()">{{ 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="ordersTable.data" size="large" v-loading="ordersTable.loading">
<template #empty>
<span>{{ !ordersTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="student_id_name" :label="t('studentId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="contract_id_name" :label="t('contractId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="amount" :label="t('amount')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('orderType')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in order_typeList">
<div v-if="item.value == row.order_type">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<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 :label="t('paymentStatus')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in payment_statusList">
<div v-if="item.value == row.payment_status">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column :label="t('paymentTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.payment_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('updateTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.update_time || '' }}
</template>
</el-table-column>
<el-table-column :label="t('isDeleted')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in is_deletedList">
<div v-if="item.value == row.is_deleted">{{ item.name }}</div>
</div>
</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="ordersTable.page" v-model:page-size="ordersTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="ordersTable.total"
@size-change="loadOrdersList()" @current-change="loadOrdersList" />
</div>
</div>
</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 { getOrdersList, deleteOrders, getWithMemberList, getWithContractsList } from '@/addon/zhjw/api/orders'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let ordersTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam:{
"student_id":"",
"contract_id":"",
"amount":[],
"order_type":"",
"pay_type":"",
"payment_status":"",
"payment_time":[],
"create_time":[]
}
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
const order_typeList = ref([] as any[])
const order_typeDictList = async () => {
order_typeList.value = await (await useDictionary('zhjw_order_type')).data.dictionary
}
order_typeDictList();
const pay_typeList = ref([] as any[])
const pay_typeDictList = async () => {
pay_typeList.value = await (await useDictionary('zhjw_pay_type')).data.dictionary
}
pay_typeDictList();
const payment_statusList = ref([] as any[])
const payment_statusDictList = async () => {
payment_statusList.value = await (await useDictionary('zhjw_payment_status')).data.dictionary
}
payment_statusDictList();
const is_deletedList = ref([] as any[])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
/**
* 获取智慧教务-订单管理列表
*/
const loadOrdersList = (page: number = 1) => {
ordersTable.loading = true
ordersTable.page = page
getOrdersList({
page: ordersTable.page,
limit: ordersTable.limit,
...ordersTable.searchParam
}).then(res => {
ordersTable.loading = false
ordersTable.data = res.data.data
ordersTable.total = res.data.total
}).catch(() => {
ordersTable.loading = false
})
}
loadOrdersList()
const router = useRouter()
/**
* 添加智慧教务-订单管理
*/
const addEvent = () => {
router.push('/orders/orders_edit')
}
/**
* 编辑智慧教务-订单管理
* @param data
*/
const editEvent = (data: any) => {
router.push('/orders/orders_edit?id='+data.id)
}
/**
* 删除智慧教务-订单管理
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('ordersDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteOrders(id).then(() => {
loadOrdersList()
}).catch(() => {
})
})
}
const studentIdList = ref([])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithMemberList({})).data
}
setStudentIdList()
const contractIdList = ref([])
const setContractIdList = async () => {
contractIdList.value = await (await getWithContractsList({})).data
}
setContractIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadOrdersList()
}
</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>

279
niucloud/addon/zhjw/admin/views/orders/orders_edit.vue

@ -0,0 +1,279 @@
<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="90px" ref="formRef" :rules="formRules" class="page-form">
<el-form-item :label="t('studentId')" prop="student_id">
<el-select class="input-width" v-model="formData.student_id" clearable :placeholder="t('studentIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in studentIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('contractId')" prop="contract_id">
<el-select class="input-width" v-model="formData.contract_id" clearable :placeholder="t('contractIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in contractIdList"
:key="index"
:label="item['title']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('amount')" prop="amount">
<el-input-number v-model="formData.amount" clearable :placeholder="t('amountPlaceholder')" class="input-width" :min = "0.01" max = "999999" />
</el-form-item>
<el-form-item :label="t('orderType')" prop="order_type">
<el-select class="input-width" v-model="formData.order_type" clearable :placeholder="t('orderTypePlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in order_typeList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</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('paymentStatus')" prop="payment_status">
<el-select class="input-width" v-model="formData.payment_status" clearable :placeholder="t('paymentStatusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in payment_statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('paymentTime')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.payment_time"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('paymentTimePlaceholder')">
</el-date-picker>
</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 { getOrdersInfo,addOrders,editOrders, getWithMemberList, getWithContractsList } from '@/addon/zhjw/api/orders';
import { useRoute } from 'vue-router'
const route = useRoute()
const id:number = parseInt(route.query.id);
const loading = ref(false)
const pageName = route.meta.title
/**
* 表单数据
*/
const initialFormData = {
id: 0,
student_id: '',
contract_id: '',
amount: '',
order_type: '',
pay_type: '',
payment_status: '',
payment_time: 0,
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const setFormData = async (id:number = 0) => {
Object.assign(formData, initialFormData)
const data = await (await getOrdersInfo(id)).data
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
if(id) setFormData(id);
const formRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
let order_typeList = ref([])
const order_typeDictList = async () => {
order_typeList.value = await (await useDictionary('zhjw_order_type')).data.dictionary
}
order_typeDictList();
watch(() => order_typeList.value, () => { formData.order_type = order_typeList.value[0].value })
let pay_typeList = ref([])
const pay_typeDictList = async () => {
pay_typeList.value = await (await useDictionary('zhjw_pay_type')).data.dictionary
}
pay_typeDictList();
watch(() => pay_typeList.value, () => { formData.pay_type = pay_typeList.value[0].value })
let payment_statusList = ref([])
const payment_statusDictList = async () => {
payment_statusList.value = await (await useDictionary('zhjw_payment_status')).data.dictionary
}
payment_statusDictList();
watch(() => payment_statusList.value, () => { formData.payment_status = payment_statusList.value[0].value })
let is_deletedList = ref([])
const is_deletedDictList = async () => {
is_deletedList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_deletedDictList();
watch(() => is_deletedList.value, () => { formData.is_deleted = is_deletedList.value[0].value })
const studentIdList = ref([] as any[])
const setStudentIdList = async () => {
studentIdList.value = await (await getWithMemberList({})).data
}
setStudentIdList()
const contractIdList = ref([] as any[])
const setContractIdList = async () => {
contractIdList.value = await (await getWithContractsList({})).data
}
setContractIdList()
//
const formRules = computed(() => {
return {
student_id: [
{ required: true, message: t('studentIdPlaceholder'), trigger: 'blur' },
]
,
contract_id: [
{ required: true, message: t('contractIdPlaceholder'), trigger: 'blur' },
]
,
amount: [
{ required: true, message: t('amountPlaceholder'), trigger: 'blur' },
{ validator: (rule: any, value: string, callback: any) => { if (value && !/^\d{0.01,999999}$/.test(value)) { callback(new Error(t('generateBetween')))} else { callback() }}},
]
,
order_type: [
{ required: true, message: t('orderTypePlaceholder'), trigger: 'blur' },
]
,
pay_type: [
{ required: true, message: t('payTypePlaceholder'), trigger: 'blur' },
]
,
payment_status: [
{ required: true, message: t('paymentStatusPlaceholder'), trigger: 'blur' },
]
,
payment_time: [
{ required: true, message: t('paymentTimePlaceholder'), 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 = id ? editOrders : addOrders
save(data).then(res => {
loading.value = false
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()
}
</script>
<style lang="scss" scoped></style>

249
niucloud/addon/zhjw/admin/views/students/students.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('addStudents') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="studentsTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('name')" prop="name">
<el-input v-model="studentsTable.searchParam.name" :placeholder="t('namePlaceholder')" />
</el-form-item>
<el-form-item :label="t('userId')" prop="user_id">
<el-select class="w-[280px]" v-model="studentsTable.searchParam.user_id" clearable :placeholder="t('userIdPlaceholder')">
<el-option
v-for="(item, index) in userIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('haveStudyTime')" prop="have_study_time">
<range-input v-model="studentsTable.searchParam.have_study_time"/>
</el-form-item>
<el-form-item :label="t('endStudyTime')" prop="end_study_time">
<range-input v-model="studentsTable.searchParam.end_study_time"/>
</el-form-item>
<el-form-item :label="t('emergencyContact')" prop="emergency_contact">
<el-input v-model="studentsTable.searchParam.emergency_contact" :placeholder="t('emergencyContactPlaceholder')" />
</el-form-item>
<el-form-item :label="t('level')" prop="level">
<el-input v-model="studentsTable.searchParam.level" :placeholder="t('levelPlaceholder')" />
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-select class="w-[280px]" v-model="studentsTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
: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="studentsTable.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="loadStudentsList()">{{ 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="studentsTable.data" size="large" v-loading="studentsTable.loading">
<template #empty>
<span>{{ !studentsTable.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="user_id_name" :label="t('userId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="have_study_time" :label="t('haveStudyTime')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="end_study_time" :label="t('endStudyTime')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="emergency_contact" :label="t('emergencyContact')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="level" :label="t('level')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('status')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in statusList">
<div v-if="item.value == row.status">{{ 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('updateTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.update_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="studentsTable.page" v-model:page-size="studentsTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="studentsTable.total"
@size-change="loadStudentsList()" @current-change="loadStudentsList" />
</div>
</div>
</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 { getStudentsList, deleteStudents, getWithUsersList } from '@/addon/zhjw/api/students'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let studentsTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam:{
"name":"",
"user_id":"",
"have_study_time":[],
"end_study_time":[],
"emergency_contact":"",
"level":"",
"status":"",
"create_time":[]
}
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
const statusList = ref([] as any[])
const statusDictList = async () => {
statusList.value = await (await useDictionary('students_status')).data.dictionary
}
statusDictList();
/**
* 获取学员管理列表
*/
const loadStudentsList = (page: number = 1) => {
studentsTable.loading = true
studentsTable.page = page
getStudentsList({
page: studentsTable.page,
limit: studentsTable.limit,
...studentsTable.searchParam
}).then(res => {
studentsTable.loading = false
studentsTable.data = res.data.data
studentsTable.total = res.data.total
}).catch(() => {
studentsTable.loading = false
})
}
loadStudentsList()
const router = useRouter()
/**
* 添加学员管理
*/
const addEvent = () => {
router.push('/students/students_edit')
}
/**
* 编辑学员管理
* @param data
*/
const editEvent = (data: any) => {
router.push('/students/students_edit?id='+data.id)
}
/**
* 删除学员管理
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('studentsDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteStudents(id).then(() => {
loadStudentsList()
}).catch(() => {
})
})
}
const userIdList = ref([])
const setUserIdList = async () => {
userIdList.value = await (await getWithUsersList({})).data
}
setUserIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadStudentsList()
}
</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>

226
niucloud/addon/zhjw/admin/views/students/students_edit.vue

@ -0,0 +1,226 @@
<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="90px" ref="formRef" :rules="formRules" class="page-form">
<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('userId')" prop="user_id">
<el-select class="input-width" v-model="formData.user_id" clearable :placeholder="t('userIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in userIdList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('haveStudyTime')" >
<el-input-number v-model="formData.have_study_time" clearable :placeholder="t('haveStudyTimePlaceholder')" class="input-width" :min = "0" max = "999999" />
</el-form-item>
<el-form-item :label="t('endStudyTime')" >
<el-input-number v-model="formData.end_study_time" clearable :placeholder="t('endStudyTimePlaceholder')" class="input-width" :min = "0" max = "999999" />
</el-form-item>
<el-form-item :label="t('emergencyContact')" >
<el-input v-model="formData.emergency_contact" clearable :placeholder="t('emergencyContactPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('level')" >
<el-input v-model="formData.level" clearable :placeholder="t('levelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</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 { getStudentsInfo,addStudents,editStudents, getWithUsersList } from '@/addon/zhjw/api/students';
import { useRoute } from 'vue-router'
const route = useRoute()
const id:number = parseInt(route.query.id);
const loading = ref(false)
const pageName = route.meta.title
/**
* 表单数据
*/
const initialFormData = {
id: 0,
name: '',
user_id: '',
have_study_time: '',
end_study_time: '',
emergency_contact: '',
level: '',
status: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const setFormData = async (id:number = 0) => {
Object.assign(formData, initialFormData)
const data = await (await getStudentsInfo(id)).data
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
if(id) setFormData(id);
const formRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
let statusList = ref([])
const statusDictList = async () => {
statusList.value = await (await useDictionary('students_status')).data.dictionary
}
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
const userIdList = ref([] as any[])
const setUserIdList = async () => {
userIdList.value = await (await getWithUsersList({})).data
}
setUserIdList()
//
const formRules = computed(() => {
return {
name: [
{ required: true, message: t('namePlaceholder'), trigger: 'blur' },
]
,
user_id: [
{ required: true, message: t('userIdPlaceholder'), trigger: 'blur' },
]
,
have_study_time: [
{ required: true, message: t('haveStudyTimePlaceholder'), trigger: 'blur' },
{ validator: (rule: any, value: string, callback: any) => { if (value && !/^\d{0,999999}$/.test(value)) { callback(new Error(t('generateBetween')))} else { callback() }}},
]
,
end_study_time: [
{ required: true, message: t('endStudyTimePlaceholder'), trigger: 'blur' },
{ validator: (rule: any, value: string, callback: any) => { if (value && !/^\d{0,999999}$/.test(value)) { callback(new Error(t('generateBetween')))} else { callback() }}},
]
,
emergency_contact: [
{ required: true, message: t('emergencyContactPlaceholder'), trigger: 'blur' },
]
,
level: [
{ required: true, message: t('levelPlaceholder'), trigger: 'blur' },
]
,
status: [
{ required: true, message: t('statusPlaceholder'), 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 = id ? editStudents : addStudents
save(data).then(res => {
loading.value = false
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()
}
</script>
<style lang="scss" scoped></style>

615
niucloud/addon/zhjw/admin/views/users/components/users-edit.vue

@ -0,0 +1,615 @@
<template>
<el-dialog v-model="showDialog" :title="formData.member_id ? t('updateUsers') : t('addUsers')" 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('memberNo')" >
<el-input v-model="formData.member_no" clearable :placeholder="t('memberNoPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('pid')" >
<el-select class="input-width" v-model="formData.pid" clearable :placeholder="t('pidPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in pidList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('username')" prop="username">
<el-input v-model="formData.username" clearable :placeholder="t('usernamePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('mobile')" prop="mobile">
<el-input v-model="formData.mobile" clearable :placeholder="t('mobilePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('password')" prop="password">
<el-input v-model="formData.password" clearable :placeholder="t('passwordPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('nickname')" prop="nickname">
<el-input v-model="formData.nickname" clearable :placeholder="t('nicknamePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('headimg')">
<upload-image v-model="formData.headimg" />
</el-form-item>
<el-form-item :label="t('memberLevel')" prop="member_level">
<el-input v-model="formData.member_level" clearable :placeholder="t('memberLevelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('memberLabel')" prop="member_label">
<el-input v-model="formData.member_label" clearable :placeholder="t('memberLabelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('wxOpenid')" >
<el-input v-model="formData.wx_openid" clearable :placeholder="t('wxOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('weappOpenid')" >
<el-input v-model="formData.weapp_openid" clearable :placeholder="t('weappOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('wxUnionid')" >
<el-input v-model="formData.wx_unionid" clearable :placeholder="t('wxUnionidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('aliOpenid')" >
<el-input v-model="formData.ali_openid" clearable :placeholder="t('aliOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('douyinOpenid')" >
<el-input v-model="formData.douyin_openid" clearable :placeholder="t('douyinOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('registerChannel')" >
<el-input v-model="formData.register_channel" clearable :placeholder="t('registerChannelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('registerType')" >
<el-input v-model="formData.register_type" clearable :placeholder="t('registerTypePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginIp')" >
<el-input v-model="formData.login_ip" clearable :placeholder="t('loginIpPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginType')" >
<el-input v-model="formData.login_type" clearable :placeholder="t('loginTypePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginChannel')" >
<el-input v-model="formData.login_channel" clearable :placeholder="t('loginChannelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginCount')" >
<el-input v-model="formData.login_count" clearable :placeholder="t('loginCountPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginTime')" >
<el-input v-model="formData.login_time" clearable :placeholder="t('loginTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('lastVisitTime')" >
<el-input v-model="formData.last_visit_time" clearable :placeholder="t('lastVisitTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('lastConsumTime')" >
<el-input v-model="formData.last_consum_time" clearable :placeholder="t('lastConsumTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('sex')" prop="sex">
<el-select class="input-width" v-model="formData.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('status')" prop="status">
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</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="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('birthdayPlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('point')" >
<el-input v-model="formData.point" clearable :placeholder="t('pointPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('pointGet')" >
<el-input v-model="formData.point_get" clearable :placeholder="t('pointGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('balance')" >
<el-input v-model="formData.balance" clearable :placeholder="t('balancePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('balanceGet')" >
<el-input v-model="formData.balance_get" clearable :placeholder="t('balanceGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('money')" >
<el-input v-model="formData.money" clearable :placeholder="t('moneyPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('moneyGet')" >
<el-input v-model="formData.money_get" clearable :placeholder="t('moneyGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('moneyCashOuting')" >
<el-input v-model="formData.money_cash_outing" clearable :placeholder="t('moneyCashOutingPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('growth')" >
<el-input v-model="formData.growth" clearable :placeholder="t('growthPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('growthGet')" >
<el-input v-model="formData.growth_get" clearable :placeholder="t('growthGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commission')" >
<el-input v-model="formData.commission" clearable :placeholder="t('commissionPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commissionGet')" >
<el-input v-model="formData.commission_get" clearable :placeholder="t('commissionGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commissionCashOuting')" >
<el-input v-model="formData.commission_cash_outing" clearable :placeholder="t('commissionCashOutingPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('isMember')" prop="is_member">
<el-select class="input-width" v-model="formData.is_member" clearable :placeholder="t('isMemberPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in is_memberList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('memberTime')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.member_time"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('memberTimePlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('address')" >
<el-input v-model="formData.address" clearable :placeholder="t('addressPlaceholder')" 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 { addUsers, editUsers, getUsersInfo, getWithUsersList } from '@/addon/zhjw/api/users'
let showDialog = ref(false)
const loading = ref(false)
/**
* 表单数据
*/
const initialFormData = {
member_id: '',
member_no: '',
pid: '',
username: '',
mobile: '',
password: '',
nickname: '',
headimg: '',
member_level: '',
member_label: '',
wx_openid: '',
weapp_openid: '',
wx_unionid: '',
ali_openid: '',
douyin_openid: '',
register_channel: '',
register_type: '',
login_ip: '',
login_type: '',
login_channel: '',
login_count: '',
login_time: '',
last_visit_time: '',
last_consum_time: '',
sex: '',
status: '',
birthday: '',
point: '',
point_get: '',
balance: '',
balance_get: '',
money: '',
money_get: '',
money_cash_outing: '',
growth: '',
growth_get: '',
commission: '',
commission_get: '',
commission_cash_outing: '',
is_member: '',
member_time: '',
address: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const formRef = ref<FormInstance>()
//
const formRules = computed(() => {
return {
member_no: [
{ required: true, message: t('memberNoPlaceholder'), trigger: 'blur' },
]
,
pid: [
{ required: true, message: t('pidPlaceholder'), trigger: 'blur' },
]
,
username: [
{ required: true, message: t('usernamePlaceholder'), trigger: 'blur' },
]
,
mobile: [
{ required: true, message: t('mobilePlaceholder'), trigger: 'blur' },
]
,
password: [
{ required: true, message: t('passwordPlaceholder'), trigger: 'blur' },
]
,
nickname: [
{ required: true, message: t('nicknamePlaceholder'), trigger: 'blur' },
]
,
headimg: [
{ required: true, message: t('headimgPlaceholder'), trigger: 'blur' },
]
,
member_level: [
{ required: true, message: t('memberLevelPlaceholder'), trigger: 'blur' },
]
,
member_label: [
{ required: true, message: t('memberLabelPlaceholder'), trigger: 'blur' },
]
,
wx_openid: [
{ required: true, message: t('wxOpenidPlaceholder'), trigger: 'blur' },
]
,
weapp_openid: [
{ required: true, message: t('weappOpenidPlaceholder'), trigger: 'blur' },
]
,
wx_unionid: [
{ required: true, message: t('wxUnionidPlaceholder'), trigger: 'blur' },
]
,
ali_openid: [
{ required: true, message: t('aliOpenidPlaceholder'), trigger: 'blur' },
]
,
douyin_openid: [
{ required: true, message: t('douyinOpenidPlaceholder'), trigger: 'blur' },
]
,
register_channel: [
{ required: true, message: t('registerChannelPlaceholder'), trigger: 'blur' },
]
,
register_type: [
{ required: true, message: t('registerTypePlaceholder'), trigger: 'blur' },
]
,
login_ip: [
{ required: true, message: t('loginIpPlaceholder'), trigger: 'blur' },
]
,
login_type: [
{ required: true, message: t('loginTypePlaceholder'), trigger: 'blur' },
]
,
login_channel: [
{ required: true, message: t('loginChannelPlaceholder'), trigger: 'blur' },
]
,
login_count: [
{ required: true, message: t('loginCountPlaceholder'), trigger: 'blur' },
]
,
login_time: [
{ required: true, message: t('loginTimePlaceholder'), trigger: 'blur' },
]
,
last_visit_time: [
{ required: true, message: t('lastVisitTimePlaceholder'), trigger: 'blur' },
]
,
last_consum_time: [
{ required: true, message: t('lastConsumTimePlaceholder'), trigger: 'blur' },
]
,
sex: [
{ required: true, message: t('sexPlaceholder'), trigger: 'blur' },
]
,
status: [
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' },
]
,
birthday: [
{ required: true, message: t('birthdayPlaceholder'), trigger: 'blur' },
]
,
point: [
{ required: true, message: t('pointPlaceholder'), trigger: 'blur' },
]
,
point_get: [
{ required: true, message: t('pointGetPlaceholder'), trigger: 'blur' },
]
,
balance: [
{ required: true, message: t('balancePlaceholder'), trigger: 'blur' },
]
,
balance_get: [
{ required: true, message: t('balanceGetPlaceholder'), trigger: 'blur' },
]
,
money: [
{ required: true, message: t('moneyPlaceholder'), trigger: 'blur' },
]
,
money_get: [
{ required: true, message: t('moneyGetPlaceholder'), trigger: 'blur' },
]
,
money_cash_outing: [
{ required: true, message: t('moneyCashOutingPlaceholder'), trigger: 'blur' },
]
,
growth: [
{ required: true, message: t('growthPlaceholder'), trigger: 'blur' },
]
,
growth_get: [
{ required: true, message: t('growthGetPlaceholder'), trigger: 'blur' },
]
,
commission: [
{ required: true, message: t('commissionPlaceholder'), trigger: 'blur' },
]
,
commission_get: [
{ required: true, message: t('commissionGetPlaceholder'), trigger: 'blur' },
]
,
commission_cash_outing: [
{ required: true, message: t('commissionCashOutingPlaceholder'), trigger: 'blur' },
]
,
is_member: [
{ required: true, message: t('isMemberPlaceholder'), trigger: 'blur' },
]
,
member_time: [
{ required: true, message: t('memberTimePlaceholder'), trigger: 'blur' },
]
,
address: [
{ required: true, message: t('addressPlaceholder'), trigger: 'blur' },
]
,
}
})
const emit = defineEmits(['complete'])
/**
* 确认
* @param formEl
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
let save = formData.member_id ? editUsers : addUsers
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 sexList = ref([])
const sexDictList = async () => {
sexList.value = await (await useDictionary('users_sex')).data.dictionary
}
sexDictList();
watch(() => sexList.value, () => { formData.sex = sexList.value[0].value })
let statusList = ref([])
const statusDictList = async () => {
statusList.value = await (await useDictionary('is_radio')).data.dictionary
}
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
let is_memberList = ref([])
const is_memberDictList = async () => {
is_memberList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_memberDictList();
watch(() => is_memberList.value, () => { formData.is_member = is_memberList.value[0].value })
let is_delList = ref([])
const is_delDictList = async () => {
is_delList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_delDictList();
watch(() => is_delList.value, () => { formData.is_del = is_delList.value[0].value })
const pidList = ref([] as any[])
const setPidList = async () => {
pidList.value = await (await getWithUsersList({})).data
}
setPidList()
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if(row){
const data = await (await getUsersInfo(row.member_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>

481
niucloud/addon/zhjw/admin/views/users/users.vue

@ -0,0 +1,481 @@
<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('addUsers') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="usersTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('username')" prop="username">
<el-input v-model="usersTable.searchParam.username" :placeholder="t('usernamePlaceholder')" />
</el-form-item>
<el-form-item :label="t('mobile')" prop="mobile">
<el-input v-model="usersTable.searchParam.mobile" :placeholder="t('mobilePlaceholder')" />
</el-form-item>
<el-form-item :label="t('nickname')" prop="nickname">
<el-input v-model="usersTable.searchParam.nickname" :placeholder="t('nicknamePlaceholder')" />
</el-form-item>
<el-form-item :label="t('memberLevel')" prop="member_level">
<el-input v-model="usersTable.searchParam.member_level" :placeholder="t('memberLevelPlaceholder')" />
</el-form-item>
<el-form-item :label="t('memberLabel')" prop="member_label">
<el-input v-model="usersTable.searchParam.member_label" :placeholder="t('memberLabelPlaceholder')" />
</el-form-item>
<el-form-item :label="t('wxOpenid')" prop="wx_openid">
<el-input v-model="usersTable.searchParam.wx_openid" :placeholder="t('wxOpenidPlaceholder')" />
</el-form-item>
<el-form-item :label="t('weappOpenid')" prop="weapp_openid">
<el-input v-model="usersTable.searchParam.weapp_openid" :placeholder="t('weappOpenidPlaceholder')" />
</el-form-item>
<el-form-item :label="t('wxUnionid')" prop="wx_unionid">
<el-input v-model="usersTable.searchParam.wx_unionid" :placeholder="t('wxUnionidPlaceholder')" />
</el-form-item>
<el-form-item :label="t('aliOpenid')" prop="ali_openid">
<el-input v-model="usersTable.searchParam.ali_openid" :placeholder="t('aliOpenidPlaceholder')" />
</el-form-item>
<el-form-item :label="t('douyinOpenid')" prop="douyin_openid">
<el-input v-model="usersTable.searchParam.douyin_openid" :placeholder="t('douyinOpenidPlaceholder')" />
</el-form-item>
<el-form-item :label="t('registerChannel')" prop="register_channel">
<el-input v-model="usersTable.searchParam.register_channel" :placeholder="t('registerChannelPlaceholder')" />
</el-form-item>
<el-form-item :label="t('registerType')" prop="register_type">
<el-input v-model="usersTable.searchParam.register_type" :placeholder="t('registerTypePlaceholder')" />
</el-form-item>
<el-form-item :label="t('loginIp')" prop="login_ip">
<el-input v-model="usersTable.searchParam.login_ip" :placeholder="t('loginIpPlaceholder')" />
</el-form-item>
<el-form-item :label="t('loginType')" prop="login_type">
<el-input v-model="usersTable.searchParam.login_type" :placeholder="t('loginTypePlaceholder')" />
</el-form-item>
<el-form-item :label="t('loginChannel')" prop="login_channel">
<el-input v-model="usersTable.searchParam.login_channel" :placeholder="t('loginChannelPlaceholder')" />
</el-form-item>
<el-form-item :label="t('loginCount')" prop="login_count">
<el-input v-model="usersTable.searchParam.login_count" :placeholder="t('loginCountPlaceholder')" />
</el-form-item>
<el-form-item :label="t('loginTime')" prop="login_time">
<el-input v-model="usersTable.searchParam.login_time" :placeholder="t('loginTimePlaceholder')" />
</el-form-item>
<el-form-item :label="t('lastVisitTime')" prop="last_visit_time">
<el-input v-model="usersTable.searchParam.last_visit_time" :placeholder="t('lastVisitTimePlaceholder')" />
</el-form-item>
<el-form-item :label="t('lastConsumTime')" prop="last_consum_time">
<el-input v-model="usersTable.searchParam.last_consum_time" :placeholder="t('lastConsumTimePlaceholder')" />
</el-form-item>
<el-form-item :label="t('sex')" prop="sex">
<el-select class="w-[280px]" v-model="usersTable.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('status')" prop="status">
<el-select class="w-[280px]" v-model="usersTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
: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="usersTable.searchParam.birthday" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item :label="t('point')" prop="point">
<el-input v-model="usersTable.searchParam.point" :placeholder="t('pointPlaceholder')" />
</el-form-item>
<el-form-item :label="t('pointGet')" prop="point_get">
<el-input v-model="usersTable.searchParam.point_get" :placeholder="t('pointGetPlaceholder')" />
</el-form-item>
<el-form-item :label="t('balance')" prop="balance">
<el-input v-model="usersTable.searchParam.balance" :placeholder="t('balancePlaceholder')" />
</el-form-item>
<el-form-item :label="t('balanceGet')" prop="balance_get">
<el-input v-model="usersTable.searchParam.balance_get" :placeholder="t('balanceGetPlaceholder')" />
</el-form-item>
<el-form-item :label="t('money')" prop="money">
<el-input v-model="usersTable.searchParam.money" :placeholder="t('moneyPlaceholder')" />
</el-form-item>
<el-form-item :label="t('moneyGet')" prop="money_get">
<el-input v-model="usersTable.searchParam.money_get" :placeholder="t('moneyGetPlaceholder')" />
</el-form-item>
<el-form-item :label="t('moneyCashOuting')" prop="money_cash_outing">
<el-input v-model="usersTable.searchParam.money_cash_outing" :placeholder="t('moneyCashOutingPlaceholder')" />
</el-form-item>
<el-form-item :label="t('growth')" prop="growth">
<el-input v-model="usersTable.searchParam.growth" :placeholder="t('growthPlaceholder')" />
</el-form-item>
<el-form-item :label="t('growthGet')" prop="growth_get">
<el-input v-model="usersTable.searchParam.growth_get" :placeholder="t('growthGetPlaceholder')" />
</el-form-item>
<el-form-item :label="t('commission')" prop="commission">
<el-input v-model="usersTable.searchParam.commission" :placeholder="t('commissionPlaceholder')" />
</el-form-item>
<el-form-item :label="t('commissionGet')" prop="commission_get">
<el-input v-model="usersTable.searchParam.commission_get" :placeholder="t('commissionGetPlaceholder')" />
</el-form-item>
<el-form-item :label="t('commissionCashOuting')" prop="commission_cash_outing">
<el-input v-model="usersTable.searchParam.commission_cash_outing" :placeholder="t('commissionCashOutingPlaceholder')" />
</el-form-item>
<el-form-item :label="t('isMember')" prop="is_member">
<el-select class="w-[280px]" v-model="usersTable.searchParam.is_member" clearable :placeholder="t('isMemberPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in is_memberList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('memberTime')" prop="member_time">
<el-date-picker v-model="usersTable.searchParam.member_time" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
: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="usersTable.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="loadUsersList()">{{ 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="usersTable.data" size="large" v-loading="usersTable.loading">
<template #empty>
<span>{{ !usersTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="member_id" :label="t('memberId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="member_no" :label="t('memberNo')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="pid_name" :label="t('pid')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="username" :label="t('username')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="mobile" :label="t('mobile')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="password" :label="t('password')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="nickname" :label="t('nickname')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('headimg')" width="100" align="left">
<template #default="{ row }">
<el-avatar v-if="row.headimg" :src="img(row.headimg)" />
<el-avatar v-else icon="UserFilled" />
</template>
</el-table-column>
<el-table-column prop="member_level" :label="t('memberLevel')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="member_label" :label="t('memberLabel')" 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="weapp_openid" :label="t('weappOpenid')" 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 prop="ali_openid" :label="t('aliOpenid')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="douyin_openid" :label="t('douyinOpenid')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="register_channel" :label="t('registerChannel')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="register_type" :label="t('registerType')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="login_ip" :label="t('loginIp')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="login_type" :label="t('loginType')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="login_channel" :label="t('loginChannel')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="login_count" :label="t('loginCount')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="login_time" :label="t('loginTime')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="last_visit_time" :label="t('lastVisitTime')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="last_consum_time" :label="t('lastConsumTime')" 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 :label="t('status')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in statusList">
<div v-if="item.value == row.status">{{ 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 prop="point" :label="t('point')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="point_get" :label="t('pointGet')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="balance" :label="t('balance')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="balance_get" :label="t('balanceGet')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="money" :label="t('money')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="money_get" :label="t('moneyGet')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="money_cash_outing" :label="t('moneyCashOuting')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="growth" :label="t('growth')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="growth_get" :label="t('growthGet')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="commission" :label="t('commission')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="commission_get" :label="t('commissionGet')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="commission_cash_outing" :label="t('commissionCashOuting')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column :label="t('isMember')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in is_memberList">
<div v-if="item.value == row.is_member">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column :label="t('memberTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.member_time || '' }}
</template>
</el-table-column>
<el-table-column prop="address" :label="t('address')" 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('updateTime')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row.update_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.member_id)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="usersTable.page" v-model:page-size="usersTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="usersTable.total"
@size-change="loadUsersList()" @current-change="loadUsersList" />
</div>
</div>
</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 { getUsersList, deleteUsers, getWithUsersList } from '@/addon/zhjw/api/users'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import { useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title;
let usersTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam:{
"username":"",
"mobile":"",
"nickname":"",
"member_level":"",
"member_label":"",
"wx_openid":"",
"weapp_openid":"",
"wx_unionid":"",
"ali_openid":"",
"douyin_openid":"",
"register_channel":"",
"register_type":"",
"login_ip":"",
"login_type":"",
"login_channel":"",
"login_count":"",
"login_time":"",
"last_visit_time":"",
"last_consum_time":"",
"sex":"",
"status":"",
"birthday":[],
"point":"",
"point_get":"",
"balance":"",
"balance_get":"",
"money":"",
"money_get":"",
"money_cash_outing":"",
"growth":"",
"growth_get":"",
"commission":"",
"commission_get":"",
"commission_cash_outing":"",
"is_member":"",
"member_time":[],
"create_time":""
}
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
const sexList = ref([] as any[])
const sexDictList = async () => {
sexList.value = await (await useDictionary('users_sex')).data.dictionary
}
sexDictList();
const statusList = ref([] as any[])
const statusDictList = async () => {
statusList.value = await (await useDictionary('is_radio')).data.dictionary
}
statusDictList();
const is_memberList = ref([] as any[])
const is_memberDictList = async () => {
is_memberList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_memberDictList();
const is_delList = ref([] as any[])
const is_delDictList = async () => {
is_delList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_delDictList();
/**
* 获取用户管理列表
*/
const loadUsersList = (page: number = 1) => {
usersTable.loading = true
usersTable.page = page
getUsersList({
page: usersTable.page,
limit: usersTable.limit,
...usersTable.searchParam
}).then(res => {
usersTable.loading = false
usersTable.data = res.data.data
usersTable.total = res.data.total
}).catch(() => {
usersTable.loading = false
})
}
loadUsersList()
const router = useRouter()
/**
* 添加用户管理
*/
const addEvent = () => {
router.push('/users/users_edit')
}
/**
* 编辑用户管理
* @param data
*/
const editEvent = (data: any) => {
router.push('/users/users_edit?id='+data.member_id)
}
/**
* 删除用户管理
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('usersDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteUsers(id).then(() => {
loadUsersList()
}).catch(() => {
})
})
}
const pidList = ref([])
const setPidList = async () => {
pidList.value = await (await getWithUsersList({})).data
}
setPidList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadUsersList()
}
</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>

612
niucloud/addon/zhjw/admin/views/users/users_edit.vue

@ -0,0 +1,612 @@
<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="90px" ref="formRef" :rules="formRules" class="page-form">
<el-form-item :label="t('memberNo')" >
<el-input v-model="formData.member_no" clearable :placeholder="t('memberNoPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('pid')" >
<el-select class="input-width" v-model="formData.pid" clearable :placeholder="t('pidPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in pidList"
:key="index"
:label="item['mobile']"
:value="item['member_id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('username')" prop="username">
<el-input v-model="formData.username" clearable :placeholder="t('usernamePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('mobile')" prop="mobile">
<el-input v-model="formData.mobile" clearable :placeholder="t('mobilePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('password')" prop="password">
<el-input v-model="formData.password" clearable :placeholder="t('passwordPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('nickname')" prop="nickname">
<el-input v-model="formData.nickname" clearable :placeholder="t('nicknamePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('headimg')">
<upload-image v-model="formData.headimg" />
</el-form-item>
<el-form-item :label="t('memberLevel')" >
<el-input v-model="formData.member_level" clearable :placeholder="t('memberLevelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('memberLabel')" >
<el-input v-model="formData.member_label" clearable :placeholder="t('memberLabelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('wxOpenid')" >
<el-input v-model="formData.wx_openid" clearable :placeholder="t('wxOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('weappOpenid')" >
<el-input v-model="formData.weapp_openid" clearable :placeholder="t('weappOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('wxUnionid')" >
<el-input v-model="formData.wx_unionid" clearable :placeholder="t('wxUnionidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('aliOpenid')" >
<el-input v-model="formData.ali_openid" clearable :placeholder="t('aliOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('douyinOpenid')" >
<el-input v-model="formData.douyin_openid" clearable :placeholder="t('douyinOpenidPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('registerChannel')" >
<el-input v-model="formData.register_channel" clearable :placeholder="t('registerChannelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('registerType')" >
<el-input v-model="formData.register_type" clearable :placeholder="t('registerTypePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginIp')" >
<el-input v-model="formData.login_ip" clearable :placeholder="t('loginIpPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginType')" >
<el-input v-model="formData.login_type" clearable :placeholder="t('loginTypePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginChannel')" >
<el-input v-model="formData.login_channel" clearable :placeholder="t('loginChannelPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginCount')" >
<el-input v-model="formData.login_count" clearable :placeholder="t('loginCountPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('loginTime')" >
<el-input v-model="formData.login_time" clearable :placeholder="t('loginTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('lastVisitTime')" >
<el-input v-model="formData.last_visit_time" clearable :placeholder="t('lastVisitTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('lastConsumTime')" >
<el-input v-model="formData.last_consum_time" clearable :placeholder="t('lastConsumTimePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('sex')" prop="sex">
<el-select class="input-width" v-model="formData.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('status')" prop="status">
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</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="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('birthdayPlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('point')" >
<el-input v-model="formData.point" clearable :placeholder="t('pointPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('pointGet')" >
<el-input v-model="formData.point_get" clearable :placeholder="t('pointGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('balance')" >
<el-input v-model="formData.balance" clearable :placeholder="t('balancePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('balanceGet')" >
<el-input v-model="formData.balance_get" clearable :placeholder="t('balanceGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('money')" >
<el-input v-model="formData.money" clearable :placeholder="t('moneyPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('moneyGet')" >
<el-input v-model="formData.money_get" clearable :placeholder="t('moneyGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('moneyCashOuting')" >
<el-input v-model="formData.money_cash_outing" clearable :placeholder="t('moneyCashOutingPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('growth')" >
<el-input v-model="formData.growth" clearable :placeholder="t('growthPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('growthGet')" >
<el-input v-model="formData.growth_get" clearable :placeholder="t('growthGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commission')" >
<el-input v-model="formData.commission" clearable :placeholder="t('commissionPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commissionGet')" >
<el-input v-model="formData.commission_get" clearable :placeholder="t('commissionGetPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('commissionCashOuting')" >
<el-input v-model="formData.commission_cash_outing" clearable :placeholder="t('commissionCashOutingPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('isMember')" prop="is_member">
<el-select class="input-width" v-model="formData.is_member" clearable :placeholder="t('isMemberPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in is_memberList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('memberTime')" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.member_time"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="t('memberTimePlaceholder')">
</el-date-picker>
</el-form-item>
<el-form-item :label="t('address')" >
<el-input v-model="formData.address" clearable :placeholder="t('addressPlaceholder')" class="input-width" />
</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 { getUsersInfo,addUsers,editUsers, getWithUsersList } from '@/addon/zhjw/api/users';
import { useRoute } from 'vue-router'
const route = useRoute()
const id:number = parseInt(route.query.id);
const loading = ref(false)
const pageName = route.meta.title
/**
* 表单数据
*/
const initialFormData = {
member_id: 0,
member_no: '',
pid: '',
username: '',
mobile: '',
password: '',
nickname: '',
headimg: '',
member_level: 0,
member_label: '',
wx_openid: '',
weapp_openid: '',
wx_unionid: '',
ali_openid: '',
douyin_openid: '',
register_channel: '',
register_type: '',
login_ip: '',
login_type: '',
login_channel: '',
login_count: 0,
login_time: 0,
last_visit_time: 0,
last_consum_time: 0,
sex: 0,
status: 0,
birthday: '',
point: 0,
point_get: 0,
balance: '',
balance_get: '',
money: '',
money_get: '',
money_cash_outing: '',
growth: 0,
growth_get: 0,
commission: '',
commission_get: '',
commission_cash_outing: '',
is_member: 0,
member_time: 0,
address: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const setFormData = async (id:number = 0) => {
Object.assign(formData, initialFormData)
const data = await (await getUsersInfo(id)).data
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
if(id) setFormData(id);
const formRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
let sexList = ref([])
const sexDictList = async () => {
sexList.value = await (await useDictionary('users_sex')).data.dictionary
}
sexDictList();
watch(() => sexList.value, () => { formData.sex = sexList.value[0].value })
let statusList = ref([])
const statusDictList = async () => {
statusList.value = await (await useDictionary('is_radio')).data.dictionary
}
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
let is_memberList = ref([])
const is_memberDictList = async () => {
is_memberList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_memberDictList();
watch(() => is_memberList.value, () => { formData.is_member = is_memberList.value[0].value })
let is_delList = ref([])
const is_delDictList = async () => {
is_delList.value = await (await useDictionary('is_radio')).data.dictionary
}
is_delDictList();
watch(() => is_delList.value, () => { formData.is_del = is_delList.value[0].value })
const pidList = ref([] as any[])
const setPidList = async () => {
pidList.value = await (await getWithUsersList({})).data
}
setPidList()
//
const formRules = computed(() => {
return {
member_no: [
{ required: true, message: t('memberNoPlaceholder'), trigger: 'blur' },
]
,
pid: [
{ required: true, message: t('pidPlaceholder'), trigger: 'blur' },
]
,
username: [
{ required: true, message: t('usernamePlaceholder'), trigger: 'blur' },
]
,
mobile: [
{ required: true, message: t('mobilePlaceholder'), trigger: 'blur' },
]
,
password: [
{ required: true, message: t('passwordPlaceholder'), trigger: 'blur' },
]
,
nickname: [
{ required: true, message: t('nicknamePlaceholder'), trigger: 'blur' },
]
,
headimg: [
{ required: true, message: t('headimgPlaceholder'), trigger: 'blur' },
]
,
member_level: [
{ required: true, message: t('memberLevelPlaceholder'), trigger: 'blur' },
]
,
member_label: [
{ required: true, message: t('memberLabelPlaceholder'), trigger: 'blur' },
]
,
wx_openid: [
{ required: true, message: t('wxOpenidPlaceholder'), trigger: 'blur' },
]
,
weapp_openid: [
{ required: true, message: t('weappOpenidPlaceholder'), trigger: 'blur' },
]
,
wx_unionid: [
{ required: true, message: t('wxUnionidPlaceholder'), trigger: 'blur' },
]
,
ali_openid: [
{ required: true, message: t('aliOpenidPlaceholder'), trigger: 'blur' },
]
,
douyin_openid: [
{ required: true, message: t('douyinOpenidPlaceholder'), trigger: 'blur' },
]
,
register_channel: [
{ required: true, message: t('registerChannelPlaceholder'), trigger: 'blur' },
]
,
register_type: [
{ required: true, message: t('registerTypePlaceholder'), trigger: 'blur' },
]
,
login_ip: [
{ required: true, message: t('loginIpPlaceholder'), trigger: 'blur' },
]
,
login_type: [
{ required: true, message: t('loginTypePlaceholder'), trigger: 'blur' },
]
,
login_channel: [
{ required: true, message: t('loginChannelPlaceholder'), trigger: 'blur' },
]
,
login_count: [
{ required: true, message: t('loginCountPlaceholder'), trigger: 'blur' },
]
,
login_time: [
{ required: true, message: t('loginTimePlaceholder'), trigger: 'blur' },
]
,
last_visit_time: [
{ required: true, message: t('lastVisitTimePlaceholder'), trigger: 'blur' },
]
,
last_consum_time: [
{ required: true, message: t('lastConsumTimePlaceholder'), trigger: 'blur' },
]
,
sex: [
{ required: true, message: t('sexPlaceholder'), trigger: 'blur' },
]
,
status: [
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' },
]
,
birthday: [
{ required: true, message: t('birthdayPlaceholder'), trigger: 'blur' },
]
,
point: [
{ required: true, message: t('pointPlaceholder'), trigger: 'blur' },
]
,
point_get: [
{ required: true, message: t('pointGetPlaceholder'), trigger: 'blur' },
]
,
balance: [
{ required: true, message: t('balancePlaceholder'), trigger: 'blur' },
]
,
balance_get: [
{ required: true, message: t('balanceGetPlaceholder'), trigger: 'blur' },
]
,
money: [
{ required: true, message: t('moneyPlaceholder'), trigger: 'blur' },
]
,
money_get: [
{ required: true, message: t('moneyGetPlaceholder'), trigger: 'blur' },
]
,
money_cash_outing: [
{ required: true, message: t('moneyCashOutingPlaceholder'), trigger: 'blur' },
]
,
growth: [
{ required: true, message: t('growthPlaceholder'), trigger: 'blur' },
]
,
growth_get: [
{ required: true, message: t('growthGetPlaceholder'), trigger: 'blur' },
]
,
commission: [
{ required: true, message: t('commissionPlaceholder'), trigger: 'blur' },
]
,
commission_get: [
{ required: true, message: t('commissionGetPlaceholder'), trigger: 'blur' },
]
,
commission_cash_outing: [
{ required: true, message: t('commissionCashOutingPlaceholder'), trigger: 'blur' },
]
,
is_member: [
{ required: true, message: t('isMemberPlaceholder'), trigger: 'blur' },
]
,
member_time: [
{ required: true, message: t('memberTimePlaceholder'), trigger: 'blur' },
]
,
address: [
{ required: true, message: t('addressPlaceholder'), 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 = id ? editUsers : addUsers
save(data).then(res => {
loading.value = false
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()
}
</script>
<style lang="scss" scoped></style>

5
niucloud/addon/zhjw/app/adminapi/controller/articles/Articles.php

@ -29,10 +29,11 @@ class Articles extends BaseAdminController
public function lists(){
$data = $this->request->params([
["title",""],
["content",""],
["category",""],
["publisher_id",""],
["status",""]
["status",""],
["create_time",["",""]],
["update_time",["",""]]
]);
return success((new ArticlesService())->getPage($data));
}

106
niucloud/addon/zhjw/app/adminapi/controller/contracts/Contracts.php

@ -0,0 +1,106 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\adminapi\controller\contracts;
use core\base\BaseAdminController;
use addon\zhjw\app\service\admin\contracts\ContractsService;
/**
* 合同管理控制器
* Class Contracts
* @package addon\zhjw\app\adminapi\controller\contracts
*/
class Contracts extends BaseAdminController
{
/**
* 获取合同管理列表
* @return \think\Response
*/
public function lists(){
$data = $this->request->params([
["student_id",""],
["title",""],
["start_date",["",""]],
["end_date",["",""]],
["status",""],
["create_time",["",""]]
]);
return success((new ContractsService())->getPage($data));
}
/**
* 合同管理详情
* @param int $id
* @return \think\Response
*/
public function info(int $id){
return success((new ContractsService())->getInfo($id));
}
/**
* 添加合同管理
* @return \think\Response
*/
public function add(){
$data = $this->request->params([
["student_id",0],
["title",""],
["content",""],
["file_data",""],
["start_date","2025-03-06 13:28:06"],
["end_date","2025-03-06 13:28:06"],
["status",""],
]);
$this->validate($data, 'addon\zhjw\app\validate\contracts\Contracts.add');
$id = (new ContractsService())->add($data);
return success('ADD_SUCCESS', ['id' => $id]);
}
/**
* 合同管理编辑
* @param $id 合同管理id
* @return \think\Response
*/
public function edit(int $id){
$data = $this->request->params([
["student_id",0],
["title",""],
["content",""],
["file_data",""],
["start_date","2025-03-06 13:28:06"],
["end_date","2025-03-06 13:28:06"],
["status",""],
]);
$this->validate($data, 'addon\zhjw\app\validate\contracts\Contracts.edit');
(new ContractsService())->edit($id, $data);
return success('EDIT_SUCCESS');
}
/**
* 合同管理删除
* @param $id 合同管理id
* @return \think\Response
*/
public function del(int $id){
(new ContractsService())->del($id);
return success('DELETE_SUCCESS');
}
public function getUsersAll(){
return success(( new ContractsService())->getUsersAll());
}
}

112
niucloud/addon/zhjw/app/adminapi/controller/orders/Orders.php

@ -0,0 +1,112 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\adminapi\controller\orders;
use core\base\BaseAdminController;
use addon\zhjw\app\service\admin\orders\OrdersService;
/**
* 智慧教务-订单管理控制器
* Class Orders
* @package addon\zhjw\app\adminapi\controller\orders
*/
class Orders extends BaseAdminController
{
/**
* 获取智慧教务-订单管理列表
* @return \think\Response
*/
public function lists(){
$data = $this->request->params([
["student_id",""],
["contract_id",""],
["amount",["",""]],
["order_type",""],
["pay_type",""],
["payment_status",""],
["payment_time",["",""]],
["create_time",["",""]]
]);
return success((new OrdersService())->getPage($data));
}
/**
* 智慧教务-订单管理详情
* @param int $id
* @return \think\Response
*/
public function info(int $id){
return success((new OrdersService())->getInfo($id));
}
/**
* 添加智慧教务-订单管理
* @return \think\Response
*/
public function add(){
$data = $this->request->params([
["student_id",0],
["contract_id",0],
["amount",0.00],
["order_type",""],
["pay_type",""],
["payment_status",""],
["payment_time",0],
]);
$this->validate($data, 'addon\zhjw\app\validate\orders\Orders.add');
$id = (new OrdersService())->add($data);
return success('ADD_SUCCESS', ['id' => $id]);
}
/**
* 智慧教务-订单管理编辑
* @param $id 智慧教务-订单管理id
* @return \think\Response
*/
public function edit(int $id){
$data = $this->request->params([
["student_id",0],
["contract_id",0],
["amount",0.00],
["order_type",""],
["pay_type",""],
["payment_status",""],
["payment_time",0],
]);
$this->validate($data, 'addon\zhjw\app\validate\orders\Orders.edit');
(new OrdersService())->edit($id, $data);
return success('EDIT_SUCCESS');
}
/**
* 智慧教务-订单管理删除
* @param $id 智慧教务-订单管理id
* @return \think\Response
*/
public function del(int $id){
(new OrdersService())->del($id);
return success('DELETE_SUCCESS');
}
public function getMemberAll(){
return success(( new OrdersService())->getMemberAll());
}
public function getContractsAll(){
return success(( new OrdersService())->getContractsAll());
}
}

108
niucloud/addon/zhjw/app/adminapi/controller/students/Students.php

@ -0,0 +1,108 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\adminapi\controller\students;
use core\base\BaseAdminController;
use addon\zhjw\app\service\admin\students\StudentsService;
/**
* 学员管理控制器
* Class Students
* @package addon\zhjw\app\adminapi\controller\students
*/
class Students extends BaseAdminController
{
/**
* 获取学员管理列表
* @return \think\Response
*/
public function lists(){
$data = $this->request->params([
["name",""],
["user_id",""],
["have_study_time",["",""]],
["end_study_time",["",""]],
["emergency_contact",""],
["level",""],
["status",""],
["create_time",["",""]]
]);
return success((new StudentsService())->getPage($data));
}
/**
* 学员管理详情
* @param int $id
* @return \think\Response
*/
public function info(int $id){
return success((new StudentsService())->getInfo($id));
}
/**
* 添加学员管理
* @return \think\Response
*/
public function add(){
$data = $this->request->params([
["name",""],
["user_id",0],
["have_study_time",0.00],
["end_study_time",0.00],
["emergency_contact",""],
["level",""],
["status",""],
]);
$this->validate($data, 'addon\zhjw\app\validate\students\Students.add');
$id = (new StudentsService())->add($data);
return success('ADD_SUCCESS', ['id' => $id]);
}
/**
* 学员管理编辑
* @param $id 学员管理id
* @return \think\Response
*/
public function edit(int $id){
$data = $this->request->params([
["name",""],
["user_id",0],
["have_study_time",0.00],
["end_study_time",0.00],
["emergency_contact",""],
["level",""],
["status",""],
]);
$this->validate($data, 'addon\zhjw\app\validate\students\Students.edit');
(new StudentsService())->edit($id, $data);
return success('EDIT_SUCCESS');
}
/**
* 学员管理删除
* @param $id 学员管理id
* @return \think\Response
*/
public function del(int $id){
(new StudentsService())->del($id);
return success('DELETE_SUCCESS');
}
public function getUsersAll(){
return success(( new StudentsService())->getUsersAll());
}
}

205
niucloud/addon/zhjw/app/adminapi/controller/users/Users.php

@ -0,0 +1,205 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\adminapi\controller\users;
use core\base\BaseAdminController;
use addon\zhjw\app\service\admin\users\UsersService;
/**
* 用户管理控制器
* Class Users
* @package addon\zhjw\app\adminapi\controller\users
*/
class Users extends BaseAdminController
{
/**
* 获取用户管理列表
* @return \think\Response
*/
public function lists(){
$data = $this->request->params([
["username",""],
["mobile",""],
["nickname",""],
["member_level",""],
["member_label",""],
["wx_openid",""],
["weapp_openid",""],
["wx_unionid",""],
["ali_openid",""],
["douyin_openid",""],
["register_channel",""],
["register_type",""],
["login_ip",""],
["login_type",""],
["login_channel",""],
["login_count",""],
["login_time",""],
["last_visit_time",""],
["last_consum_time",""],
["sex",""],
["status",""],
["birthday",["",""]],
["point",""],
["point_get",""],
["balance",""],
["balance_get",""],
["money",""],
["money_get",""],
["money_cash_outing",""],
["growth",""],
["growth_get",""],
["commission",""],
["commission_get",""],
["commission_cash_outing",""],
["is_member",""],
["member_time",["",""]],
["create_time",""]
]);
return success((new UsersService())->getPage($data));
}
/**
* 用户管理详情
* @param int $id
* @return \think\Response
*/
public function info(int $id){
return success((new UsersService())->getInfo($id));
}
/**
* 添加用户管理
* @return \think\Response
*/
public function add(){
$data = $this->request->params([
["member_no",""],
["pid",0],
["username",""],
["mobile",""],
["password",""],
["nickname",""],
["headimg",""],
["member_level",0],
["member_label",""],
["wx_openid",""],
["weapp_openid",""],
["wx_unionid",""],
["ali_openid",""],
["douyin_openid",""],
["register_channel",""],
["register_type",""],
["login_ip",""],
["login_type",""],
["login_channel",""],
["login_count",0],
["login_time",0],
["last_visit_time",0],
["last_consum_time",0],
["sex",0],
["status",0],
["birthday",""],
["point",0],
["point_get",0],
["balance",0.00],
["balance_get",0.00],
["money",0.00],
["money_get",0.00],
["money_cash_outing",0.00],
["growth",0],
["growth_get",0],
["commission",0.00],
["commission_get",0.00],
["commission_cash_outing",0.00],
["is_member",0],
["member_time",0],
["address",""],
]);
$this->validate($data, 'addon\zhjw\app\validate\users\Users.add');
$id = (new UsersService())->add($data);
return success('ADD_SUCCESS', ['id' => $id]);
}
/**
* 用户管理编辑
* @param $id 用户管理id
* @return \think\Response
*/
public function edit(int $id){
$data = $this->request->params([
["member_no",""],
["pid",0],
["username",""],
["mobile",""],
["password",""],
["nickname",""],
["headimg",""],
["member_level",0],
["member_label",""],
["wx_openid",""],
["weapp_openid",""],
["wx_unionid",""],
["ali_openid",""],
["douyin_openid",""],
["register_channel",""],
["register_type",""],
["login_ip",""],
["login_type",""],
["login_channel",""],
["login_count",0],
["login_time",0],
["last_visit_time",0],
["last_consum_time",0],
["sex",0],
["status",0],
["birthday",""],
["point",0],
["point_get",0],
["balance",0.00],
["balance_get",0.00],
["money",0.00],
["money_get",0.00],
["money_cash_outing",0.00],
["growth",0],
["growth_get",0],
["commission",0.00],
["commission_get",0.00],
["commission_cash_outing",0.00],
["is_member",0],
["member_time",0],
["address",""],
]);
$this->validate($data, 'addon\zhjw\app\validate\users\Users.edit');
(new UsersService())->edit($id, $data);
return success('EDIT_SUCCESS');
}
/**
* 用户管理删除
* @param $id 用户管理id
* @return \think\Response
*/
public function del(int $id){
(new UsersService())->del($id);
return success('DELETE_SUCCESS');
}
public function getUsersAll(){
return success(( new UsersService())->getUsersAll());
}
}

111
niucloud/addon/zhjw/app/adminapi/route/route.php

@ -28,6 +28,37 @@ Route::group('zhjw', function () {
AdminCheckRole::class,
AdminLog::class
]);
// USER_CODE_BEGIN -- zhjw_orders
Route::group('zhjw', function () {
//智慧教务-订单管理列表
Route::get('orders', 'addon\zhjw\app\adminapi\controller\orders\Orders@lists');
//智慧教务-订单管理详情
Route::get('orders/:id', 'addon\zhjw\app\adminapi\controller\orders\Orders@info');
//添加智慧教务-订单管理
Route::post('orders', 'addon\zhjw\app\adminapi\controller\orders\Orders@add');
//编辑智慧教务-订单管理
Route::put('orders/:id', 'addon\zhjw\app\adminapi\controller\orders\Orders@edit');
//删除智慧教务-订单管理
Route::delete('orders/:id', 'addon\zhjw\app\adminapi\controller\orders\Orders@del');
Route::get('member_all','addon\zhjw\app\adminapi\controller\orders\Orders@getMemberAll');
Route::get('contracts_all','addon\zhjw\app\adminapi\controller\orders\Orders@getContractsAll');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,
AdminLog::class
]);
// USER_CODE_END -- zhjw_orders
// USER_CODE_BEGIN -- zhjw_articles
Route::group('zhjw', function () {
@ -51,3 +82,83 @@ Route::group('zhjw', function () {
AdminLog::class
]);
// USER_CODE_END -- zhjw_articles
// USER_CODE_BEGIN -- zhjw_users
Route::group('zhjw', function () {
//用户管理列表
Route::get('users', 'addon\zhjw\app\adminapi\controller\users\Users@lists');
//用户管理详情
Route::get('users/:id', 'addon\zhjw\app\adminapi\controller\users\Users@info');
//添加用户管理
Route::post('users', 'addon\zhjw\app\adminapi\controller\users\Users@add');
//编辑用户管理
Route::put('users/:id', 'addon\zhjw\app\adminapi\controller\users\Users@edit');
//删除用户管理
Route::delete('users/:id', 'addon\zhjw\app\adminapi\controller\users\Users@del');
Route::get('users_all','addon\zhjw\app\adminapi\controller\users\Users@getUsersAll');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,
AdminLog::class
]);
// USER_CODE_END -- zhjw_users
// USER_CODE_BEGIN -- zhjw_students
Route::group('zhjw', function () {
//学员管理列表
Route::get('students', 'addon\zhjw\app\adminapi\controller\students\Students@lists');
//学员管理详情
Route::get('students/:id', 'addon\zhjw\app\adminapi\controller\students\Students@info');
//添加学员管理
Route::post('students', 'addon\zhjw\app\adminapi\controller\students\Students@add');
//编辑学员管理
Route::put('students/:id', 'addon\zhjw\app\adminapi\controller\students\Students@edit');
//删除学员管理
Route::delete('students/:id', 'addon\zhjw\app\adminapi\controller\students\Students@del');
Route::get('users_all','addon\zhjw\app\adminapi\controller\students\Students@getUsersAll');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,
AdminLog::class
]);
// USER_CODE_END -- zhjw_students
// USER_CODE_BEGIN -- zhjw_contracts
Route::group('zhjw', function () {
//合同管理列表
Route::get('contracts', 'addon\zhjw\app\adminapi\controller\contracts\Contracts@lists');
//合同管理详情
Route::get('contracts/:id', 'addon\zhjw\app\adminapi\controller\contracts\Contracts@info');
//添加合同管理
Route::post('contracts', 'addon\zhjw\app\adminapi\controller\contracts\Contracts@add');
//编辑合同管理
Route::put('contracts/:id', 'addon\zhjw\app\adminapi\controller\contracts\Contracts@edit');
//删除合同管理
Route::delete('contracts/:id', 'addon\zhjw\app\adminapi\controller\contracts\Contracts@del');
Route::get('users_all','addon\zhjw\app\adminapi\controller\contracts\Contracts@getUsersAll');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,
AdminLog::class
]);
// USER_CODE_END -- zhjw_contracts

52
niucloud/addon/zhjw/app/model/articles/Articles.php

@ -44,7 +44,7 @@ class Articles extends BaseModel
* 定义软删除标记字段.
* @var string
*/
protected $deleteTime = 'delete_time';
protected $deleteTime = 'is_deleted';
/**
* 定义软删除字段的默认值.
@ -64,18 +64,6 @@ class Articles extends BaseModel
}
}
/**
* 搜索器:文章管理内容
* @param $value
* @param $data
*/
public function searchContentAttr($query, $value, $data)
{
if ($value) {
$query->where("content", "like", "%".$value."%");
}
}
/**
* 搜索器:文章管理文章分类
* @param $value
@ -112,13 +100,49 @@ class Articles extends BaseModel
}
}
/**
* 搜索器:文章管理添加时间
* @param $value
* @param $data
*/
public function searchCreateTimeAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["create_time", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["create_time", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["create_time", "<=", $end]]);
}
}
/**
* 搜索器:文章管理更新时间
* @param $value
* @param $data
*/
public function searchUpdateTimeAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["update_time", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["update_time", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["update_time", "<=", $end]]);
}
}
public function sysUser(){
return $this->hasOne(SysUser::class, 'real_name', 'publisher_id')->joinType('left')->withField('uid,real_name')->bind(['publisher_id_name'=>'uid']);
return $this->hasOne(SysUser::class, 'uid', 'publisher_id')->joinType('left')->withField('username,uid')->bind(['publisher_id_name'=>'username']);
}
}

154
niucloud/addon/zhjw/app/model/contracts/Contracts.php

@ -0,0 +1,154 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\model\contracts;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
use addon\zhjw\app\model\users\Users;
/**
* 合同管理模型
* Class Contracts
* @package addon\zhjw\app\model\contracts
*/
class Contracts extends BaseModel
{
use SoftDelete;
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
/**
* 模型名称
* @var string
*/
protected $name = 'zhjw_contracts';
/**
* 定义软删除标记字段.
* @var string
*/
protected $deleteTime = 'is_deleted';
/**
* 定义软删除字段的默认值.
* @var int
*/
protected $defaultSoftDelete = 0;
/**
* 搜索器:合同管理学员
* @param $value
* @param $data
*/
public function searchStudentIdAttr($query, $value, $data)
{
if ($value) {
$query->where("student_id", $value);
}
}
/**
* 搜索器:合同管理合同名称
* @param $value
* @param $data
*/
public function searchTitleAttr($query, $value, $data)
{
if ($value) {
$query->where("title", "like", "%".$value."%");
}
}
/**
* 搜索器:合同管理生效日期
* @param $value
* @param $data
*/
public function searchStartDateAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["start_date", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["start_date", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["start_date", "<=", $end]]);
}
}
/**
* 搜索器:合同管理终止日期
* @param $value
* @param $data
*/
public function searchEndDateAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["end_date", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["end_date", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["end_date", "<=", $end]]);
}
}
/**
* 搜索器:合同管理状态
* @param $value
* @param $data
*/
public function searchStatusAttr($query, $value, $data)
{
if ($value) {
$query->where("status", $value);
}
}
/**
* 搜索器:合同管理添加时间
* @param $value
* @param $data
*/
public function searchCreateTimeAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["create_time", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["create_time", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["create_time", "<=", $end]]);
}
}
public function users(){
return $this->hasOne(Users::class, 'member_id', 'student_id')->joinType('left')->withField('mobile,member_id')->bind(['student_id_name'=>'mobile']);
}
}

184
niucloud/addon/zhjw/app/model/orders/Orders.php

@ -0,0 +1,184 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\model\orders;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
use app\model\member\Member;
use addon\zhjw\app\model\contracts\Contracts;
/**
* 智慧教务-订单管理模型
* Class Orders
* @package addon\zhjw\app\model\orders
*/
class Orders extends BaseModel
{
use SoftDelete;
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
/**
* 模型名称
* @var string
*/
protected $name = 'zhjw_orders';
/**
* 定义软删除标记字段.
* @var string
*/
protected $deleteTime = 'is_deleted';
/**
* 定义软删除字段的默认值.
* @var int
*/
protected $defaultSoftDelete = 0;
/**
* 搜索器:智慧教务-订单管理学员
* @param $value
* @param $data
*/
public function searchStudentIdAttr($query, $value, $data)
{
if ($value) {
$query->where("student_id", $value);
}
}
/**
* 搜索器:智慧教务-订单管理关联合同
* @param $value
* @param $data
*/
public function searchContractIdAttr($query, $value, $data)
{
if ($value) {
$query->where("contract_id", "like", "%".$value."%");
}
}
/**
* 搜索器:智慧教务-订单管理订单金额
* @param $value
* @param $data
*/
public function searchAmountAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : $value[0];
$end = empty($value[1]) ? 0 : $value[1];
if ($start > 0 && $end > 0) {
$query->where([["amount", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["amount", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["amount", "<=", $end]]);
}
}
/**
* 搜索器:智慧教务-订单管理订单类型
* @param $value
* @param $data
*/
public function searchOrderTypeAttr($query, $value, $data)
{
if ($value) {
$query->where("order_type", $value);
}
}
/**
* 搜索器:智慧教务-订单管理支付类型
* @param $value
* @param $data
*/
public function searchPayTypeAttr($query, $value, $data)
{
if ($value) {
$query->where("pay_type", $value);
}
}
/**
* 搜索器:智慧教务-订单管理支付状态
* @param $value
* @param $data
*/
public function searchPaymentStatusAttr($query, $value, $data)
{
if ($value) {
$query->where("payment_status", $value);
}
}
/**
* 搜索器:智慧教务-订单管理支付时间
* @param $value
* @param $data
*/
public function searchPaymentTimeAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["payment_time", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["payment_time", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["payment_time", "<=", $end]]);
}
}
/**
* 搜索器:智慧教务-订单管理添加时间
* @param $value
* @param $data
*/
public function searchCreateTimeAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["create_time", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["create_time", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["create_time", "<=", $end]]);
}
}
public function member(){
return $this->hasOne(Member::class, 'member_id', 'student_id')->joinType('left')->withField('mobile,member_id')->bind(['student_id_name'=>'mobile']);
}
public function contracts(){
return $this->hasOne(Contracts::class, 'id', 'contract_id')->joinType('left')->withField('title,id')->bind(['contract_id_name'=>'title']);
}
}

178
niucloud/addon/zhjw/app/model/students/Students.php

@ -0,0 +1,178 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\model\students;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
use addon\zhjw\app\model\users\Users;
/**
* 学员管理模型
* Class Students
* @package addon\zhjw\app\model\students
*/
class Students extends BaseModel
{
use SoftDelete;
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
/**
* 模型名称
* @var string
*/
protected $name = 'zhjw_students';
/**
* 定义软删除标记字段.
* @var string
*/
protected $deleteTime = 'is_deleted';
/**
* 定义软删除字段的默认值.
* @var int
*/
protected $defaultSoftDelete = 0;
/**
* 搜索器:学员管理姓名
* @param $value
* @param $data
*/
public function searchNameAttr($query, $value, $data)
{
if ($value) {
$query->where("name", "like", "%".$value."%");
}
}
/**
* 搜索器:学员管理关联用户
* @param $value
* @param $data
*/
public function searchUserIdAttr($query, $value, $data)
{
if ($value) {
$query->where("user_id", $value);
}
}
/**
* 搜索器:学员管理学员有效学时
* @param $value
* @param $data
*/
public function searchHaveStudyTimeAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : $value[0];
$end = empty($value[1]) ? 0 : $value[1];
if ($start > 0 && $end > 0) {
$query->where([["have_study_time", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["have_study_time", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["have_study_time", "<=", $end]]);
}
}
/**
* 搜索器:学员管理学员完成学时
* @param $value
* @param $data
*/
public function searchEndStudyTimeAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : $value[0];
$end = empty($value[1]) ? 0 : $value[1];
if ($start > 0 && $end > 0) {
$query->where([["end_study_time", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["end_study_time", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["end_study_time", "<=", $end]]);
}
}
/**
* 搜索器:学员管理紧急联系人
* @param $value
* @param $data
*/
public function searchEmergencyContactAttr($query, $value, $data)
{
if ($value) {
$query->where("emergency_contact", "like", "%".$value."%");
}
}
/**
* 搜索器:学员管理学员等级
* @param $value
* @param $data
*/
public function searchLevelAttr($query, $value, $data)
{
if ($value) {
$query->where("level", $value);
}
}
/**
* 搜索器:学员管理状态
* @param $value
* @param $data
*/
public function searchStatusAttr($query, $value, $data)
{
if ($value) {
$query->where("status", $value);
}
}
/**
* 搜索器:学员管理添加时间
* @param $value
* @param $data
*/
public function searchCreateTimeAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["create_time", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["create_time", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["create_time", "<=", $end]]);
}
}
public function users(){
return $this->hasOne(Users::class, 'member_id', 'user_id')->joinType('left')->withField('mobile,member_id')->bind(['user_id_name'=>'mobile']);
}
}

520
niucloud/addon/zhjw/app/model/users/Users.php

@ -0,0 +1,520 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\model\users;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
use addon\zhjw\app\model\users\Users;
/**
* 用户管理模型
* Class Users
* @package addon\zhjw\app\model\users
*/
class Users extends BaseModel
{
use SoftDelete;
/**
* 数据表主键
* @var string
*/
protected $pk = 'member_id';
/**
* 模型名称
* @var string
*/
protected $name = 'zhjw_users';
/**
* 定义软删除标记字段.
* @var string
*/
protected $deleteTime = 'is_del';
/**
* 定义软删除字段的默认值.
* @var int
*/
protected $defaultSoftDelete = 0;
/**
* 搜索器:用户管理会员用户名
* @param $value
* @param $data
*/
public function searchUsernameAttr($query, $value, $data)
{
if ($value) {
$query->where("username", "like", "%".$value."%");
}
}
/**
* 搜索器:用户管理手机号
* @param $value
* @param $data
*/
public function searchMobileAttr($query, $value, $data)
{
if ($value) {
$query->where("mobile", "like", "%".$value."%");
}
}
/**
* 搜索器:用户管理会员昵称
* @param $value
* @param $data
*/
public function searchNicknameAttr($query, $value, $data)
{
if ($value) {
$query->where("nickname", "like", "%".$value."%");
}
}
/**
* 搜索器:用户管理会员等级
* @param $value
* @param $data
*/
public function searchMemberLevelAttr($query, $value, $data)
{
if ($value) {
$query->where("member_level", $value);
}
}
/**
* 搜索器:用户管理会员标签
* @param $value
* @param $data
*/
public function searchMemberLabelAttr($query, $value, $data)
{
if ($value) {
$query->where("member_label", $value);
}
}
/**
* 搜索器:用户管理微信用户openid
* @param $value
* @param $data
*/
public function searchWxOpenidAttr($query, $value, $data)
{
if ($value) {
$query->where("wx_openid", $value);
}
}
/**
* 搜索器:用户管理微信小程序openid
* @param $value
* @param $data
*/
public function searchWeappOpenidAttr($query, $value, $data)
{
if ($value) {
$query->where("weapp_openid", $value);
}
}
/**
* 搜索器:用户管理微信unionid
* @param $value
* @param $data
*/
public function searchWxUnionidAttr($query, $value, $data)
{
if ($value) {
$query->where("wx_unionid", $value);
}
}
/**
* 搜索器:用户管理支付宝账户id
* @param $value
* @param $data
*/
public function searchAliOpenidAttr($query, $value, $data)
{
if ($value) {
$query->where("ali_openid", $value);
}
}
/**
* 搜索器:用户管理抖音小程序openid
* @param $value
* @param $data
*/
public function searchDouyinOpenidAttr($query, $value, $data)
{
if ($value) {
$query->where("douyin_openid", $value);
}
}
/**
* 搜索器:用户管理注册来源
* @param $value
* @param $data
*/
public function searchRegisterChannelAttr($query, $value, $data)
{
if ($value) {
$query->where("register_channel", $value);
}
}
/**
* 搜索器:用户管理注册方式
* @param $value
* @param $data
*/
public function searchRegisterTypeAttr($query, $value, $data)
{
if ($value) {
$query->where("register_type", $value);
}
}
/**
* 搜索器:用户管理当前登录ip
* @param $value
* @param $data
*/
public function searchLoginIpAttr($query, $value, $data)
{
if ($value) {
$query->where("login_ip", $value);
}
}
/**
* 搜索器:用户管理当前登录的操作终端类型
* @param $value
* @param $data
*/
public function searchLoginTypeAttr($query, $value, $data)
{
if ($value) {
$query->where("login_type", $value);
}
}
/**
* 搜索器:用户管理登录渠道
* @param $value
* @param $data
*/
public function searchLoginChannelAttr($query, $value, $data)
{
if ($value) {
$query->where("login_channel", $value);
}
}
/**
* 搜索器:用户管理登录次数
* @param $value
* @param $data
*/
public function searchLoginCountAttr($query, $value, $data)
{
if ($value) {
$query->where("login_count", $value);
}
}
/**
* 搜索器:用户管理当前登录时间
* @param $value
* @param $data
*/
public function searchLoginTimeAttr($query, $value, $data)
{
if ($value) {
$query->where("login_time", $value);
}
}
/**
* 搜索器:用户管理最后访问时间
* @param $value
* @param $data
*/
public function searchLastVisitTimeAttr($query, $value, $data)
{
if ($value) {
$query->where("last_visit_time", $value);
}
}
/**
* 搜索器:用户管理最后消费时间
* @param $value
* @param $data
*/
public function searchLastConsumTimeAttr($query, $value, $data)
{
if ($value) {
$query->where("last_consum_time", $value);
}
}
/**
* 搜索器:用户管理性别
* @param $value
* @param $data
*/
public function searchSexAttr($query, $value, $data)
{
if ($value) {
$query->where("sex", $value);
}
}
/**
* 搜索器:用户管理用户状态
* @param $value
* @param $data
*/
public function searchStatusAttr($query, $value, $data)
{
if ($value) {
$query->where("status", $value);
}
}
/**
* 搜索器:用户管理出生日期
* @param $value
* @param $data
*/
public function searchBirthdayAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["birthday", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["birthday", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["birthday", "<=", $end]]);
}
}
/**
* 搜索器:用户管理可用积分
* @param $value
* @param $data
*/
public function searchPointAttr($query, $value, $data)
{
if ($value) {
$query->where("point", $value);
}
}
/**
* 搜索器:用户管理累计获取积分
* @param $value
* @param $data
*/
public function searchPointGetAttr($query, $value, $data)
{
if ($value) {
$query->where("point_get", $value);
}
}
/**
* 搜索器:用户管理可用余额
* @param $value
* @param $data
*/
public function searchBalanceAttr($query, $value, $data)
{
if ($value) {
$query->where("balance", $value);
}
}
/**
* 搜索器:用户管理累计获取余额
* @param $value
* @param $data
*/
public function searchBalanceGetAttr($query, $value, $data)
{
if ($value) {
$query->where("balance_get", $value);
}
}
/**
* 搜索器:用户管理可用余额(可提现)
* @param $value
* @param $data
*/
public function searchMoneyAttr($query, $value, $data)
{
if ($value) {
$query->where("money", $value);
}
}
/**
* 搜索器:用户管理累计获取余额(可提现)
* @param $value
* @param $data
*/
public function searchMoneyGetAttr($query, $value, $data)
{
if ($value) {
$query->where("money_get", $value);
}
}
/**
* 搜索器:用户管理提现中余额(可提现)
* @param $value
* @param $data
*/
public function searchMoneyCashOutingAttr($query, $value, $data)
{
if ($value) {
$query->where("money_cash_outing", $value);
}
}
/**
* 搜索器:用户管理成长值
* @param $value
* @param $data
*/
public function searchGrowthAttr($query, $value, $data)
{
if ($value) {
$query->where("growth", $value);
}
}
/**
* 搜索器:用户管理累计获得成长值
* @param $value
* @param $data
*/
public function searchGrowthGetAttr($query, $value, $data)
{
if ($value) {
$query->where("growth_get", $value);
}
}
/**
* 搜索器:用户管理当前佣金
* @param $value
* @param $data
*/
public function searchCommissionAttr($query, $value, $data)
{
if ($value) {
$query->where("commission", $value);
}
}
/**
* 搜索器:用户管理佣金获取
* @param $value
* @param $data
*/
public function searchCommissionGetAttr($query, $value, $data)
{
if ($value) {
$query->where("commission_get", $value);
}
}
/**
* 搜索器:用户管理提现中佣金
* @param $value
* @param $data
*/
public function searchCommissionCashOutingAttr($query, $value, $data)
{
if ($value) {
$query->where("commission_cash_outing", $value);
}
}
/**
* 搜索器:用户管理是否是会员
* @param $value
* @param $data
*/
public function searchIsMemberAttr($query, $value, $data)
{
if ($value) {
$query->where("is_member", $value);
}
}
/**
* 搜索器:用户管理成为会员时间
* @param $value
* @param $data
*/
public function searchMemberTimeAttr($query, $value, $data)
{
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["member_time", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["member_time", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["member_time", "<=", $end]]);
}
}
/**
* 搜索器:用户管理注册时间
* @param $value
* @param $data
*/
public function searchCreateTimeAttr($query, $value, $data)
{
if ($value) {
$query->where("create_time", $value);
}
}
public function users(){
return $this->hasOne(Users::class, 'member_id', 'pid')->joinType('left')->withField('mobile,member_id')->bind(['pid_name'=>'mobile']);
}
}

8
niucloud/addon/zhjw/app/service/admin/articles/ArticlesService.php

@ -37,10 +37,10 @@ class ArticlesService extends BaseAdminService
*/
public function getPage(array $where = [])
{
$field = 'id,title,content,category,publisher_id,status,create_time,update_time,delete_time';
$field = 'id,title,content,category,publisher_id,status,create_time,update_time,is_deleted,created_by,created_role,updated_by,updated_role';
$order = 'id desc';
$search_model = $this->model->withSearch(["title","content","category","publisher_id","status"], $where)->with(['sysUser'])->field($field)->order($order);
$search_model = $this->model->withSearch(["title","category","publisher_id","status","create_time","update_time"], $where)->with(['sysUser'])->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
@ -52,10 +52,10 @@ class ArticlesService extends BaseAdminService
*/
public function getInfo(int $id)
{
$field = 'id,title,content,category,publisher_id,status,create_time,update_time,delete_time';
$field = 'id,title,content,category,publisher_id,status,create_time,update_time,is_deleted,created_by,created_role,updated_by,updated_role';
$info = $this->model->field($field)->where([['id', "=", $id]])->with(['sysUser'])->findOrEmpty()->toArray();
$info['status'] = strval($info['status']);
$info['is_deleted'] = strval($info['is_deleted']);
return $info;
}

105
niucloud/addon/zhjw/app/service/admin/contracts/ContractsService.php

@ -0,0 +1,105 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\service\admin\contracts;
use addon\zhjw\app\model\contracts\Contracts;
use addon\zhjw\app\model\users\Users;
use core\base\BaseAdminService;
/**
* 合同管理服务层
* Class ContractsService
* @package addon\zhjw\app\service\admin\contracts
*/
class ContractsService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new Contracts();
}
/**
* 获取合同管理列表
* @param array $where
* @return array
*/
public function getPage(array $where = [])
{
$field = 'id,student_id,title,content,file_data,start_date,end_date,status,create_time,update_time,is_deleted,created_by,created_role,updated_by,updated_role';
$order = 'id desc';
$search_model = $this->model->withSearch(["student_id","title","start_date","end_date","status","create_time"], $where)->with(['users'])->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
/**
* 获取合同管理信息
* @param int $id
* @return array
*/
public function getInfo(int $id)
{
$field = 'id,student_id,title,content,file_data,start_date,end_date,status,create_time,update_time,is_deleted,created_by,created_role,updated_by,updated_role';
$info = $this->model->field($field)->where([['id', "=", $id]])->with(['users'])->findOrEmpty()->toArray();
return $info;
}
/**
* 添加合同管理
* @param array $data
* @return mixed
*/
public function add(array $data)
{
$res = $this->model->create($data);
return $res->id;
}
/**
* 合同管理编辑
* @param int $id
* @param array $data
* @return bool
*/
public function edit(int $id, array $data)
{
$this->model->where([['id', '=', $id]])->update($data);
return true;
}
/**
* 删除合同管理
* @param int $id
* @return bool
*/
public function del(int $id)
{
$model = $this->model->where([['id', '=', $id]])->find();
$res = $model->delete();
return $res;
}
public function getUsersAll(){
$usersModel = new Users();
return $usersModel->select()->toArray();
}
}

112
niucloud/addon/zhjw/app/service/admin/orders/OrdersService.php

@ -0,0 +1,112 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\service\admin\orders;
use addon\zhjw\app\model\orders\Orders;
use app\model\member\Member;
use addon\zhjw\app\model\contracts\Contracts;
use core\base\BaseAdminService;
/**
* 智慧教务-订单管理服务层
* Class OrdersService
* @package addon\zhjw\app\service\admin\orders
*/
class OrdersService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new Orders();
}
/**
* 获取智慧教务-订单管理列表
* @param array $where
* @return array
*/
public function getPage(array $where = [])
{
$field = 'id,student_id,contract_id,amount,order_type,pay_type,payment_status,payment_time,create_time,update_time,is_deleted,created_by,created_role,updated_by,updated_role';
$order = 'id desc';
$search_model = $this->model->withSearch(["student_id","contract_id","amount","order_type","pay_type","payment_status","payment_time","create_time"], $where)->with(['member','contracts'])->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
/**
* 获取智慧教务-订单管理信息
* @param int $id
* @return array
*/
public function getInfo(int $id)
{
$field = 'id,student_id,contract_id,amount,order_type,pay_type,payment_status,payment_time,create_time,update_time,is_deleted,created_by,created_role,updated_by,updated_role';
$info = $this->model->field($field)->where([['id', "=", $id]])->with(['member','contracts'])->findOrEmpty()->toArray();
$info['is_deleted'] = strval($info['is_deleted']);
return $info;
}
/**
* 添加智慧教务-订单管理
* @param array $data
* @return mixed
*/
public function add(array $data)
{
$res = $this->model->create($data);
return $res->id;
}
/**
* 智慧教务-订单管理编辑
* @param int $id
* @param array $data
* @return bool
*/
public function edit(int $id, array $data)
{
$this->model->where([['id', '=', $id]])->update($data);
return true;
}
/**
* 删除智慧教务-订单管理
* @param int $id
* @return bool
*/
public function del(int $id)
{
$model = $this->model->where([['id', '=', $id]])->find();
$res = $model->delete();
return $res;
}
public function getMemberAll(){
$memberModel = new Member();
return $memberModel->select()->toArray();
}
public function getContractsAll(){
$contractsModel = new Contracts();
return $contractsModel->select()->toArray();
}
}

105
niucloud/addon/zhjw/app/service/admin/students/StudentsService.php

@ -0,0 +1,105 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\service\admin\students;
use addon\zhjw\app\model\students\Students;
use addon\zhjw\app\model\users\Users;
use core\base\BaseAdminService;
/**
* 学员管理服务层
* Class StudentsService
* @package addon\zhjw\app\service\admin\students
*/
class StudentsService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new Students();
}
/**
* 获取学员管理列表
* @param array $where
* @return array
*/
public function getPage(array $where = [])
{
$field = 'id,name,user_id,have_study_time,end_study_time,emergency_contact,level,status,create_time,update_time,is_deleted,created_by,created_role,updated_by,updated_role';
$order = 'id desc';
$search_model = $this->model->withSearch(["name","user_id","have_study_time","end_study_time","emergency_contact","level","status","create_time"], $where)->with(['users'])->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
/**
* 获取学员管理信息
* @param int $id
* @return array
*/
public function getInfo(int $id)
{
$field = 'id,name,user_id,have_study_time,end_study_time,emergency_contact,level,status,create_time,update_time,is_deleted,created_by,created_role,updated_by,updated_role';
$info = $this->model->field($field)->where([['id', "=", $id]])->with(['users'])->findOrEmpty()->toArray();
return $info;
}
/**
* 添加学员管理
* @param array $data
* @return mixed
*/
public function add(array $data)
{
$res = $this->model->create($data);
return $res->id;
}
/**
* 学员管理编辑
* @param int $id
* @param array $data
* @return bool
*/
public function edit(int $id, array $data)
{
$this->model->where([['id', '=', $id]])->update($data);
return true;
}
/**
* 删除学员管理
* @param int $id
* @return bool
*/
public function del(int $id)
{
$model = $this->model->where([['id', '=', $id]])->find();
$res = $model->delete();
return $res;
}
public function getUsersAll(){
$usersModel = new Users();
return $usersModel->select()->toArray();
}
}

104
niucloud/addon/zhjw/app/service/admin/users/UsersService.php

@ -0,0 +1,104 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\service\admin\users;
use addon\zhjw\app\model\users\Users;
use core\base\BaseAdminService;
/**
* 用户管理服务层
* Class UsersService
* @package addon\zhjw\app\service\admin\users
*/
class UsersService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new Users();
}
/**
* 获取用户管理列表
* @param array $where
* @return array
*/
public function getPage(array $where = [])
{
$field = 'member_id,member_no,pid,username,mobile,password,nickname,headimg,member_level,member_label,wx_openid,weapp_openid,wx_unionid,ali_openid,douyin_openid,register_channel,register_type,login_ip,login_type,login_channel,login_count,login_time,last_visit_time,last_consum_time,sex,status,birthday,point,point_get,balance,balance_get,money,money_get,money_cash_outing,growth,growth_get,commission,commission_get,commission_cash_outing,is_member,member_time,is_del,province_id,city_id,district_id,address,location,delete_time,create_time,update_time,created_by,created_role,updated_by,updated_role';
$order = 'member_id desc';
$search_model = $this->model->withSearch(["username","mobile","nickname","member_level","member_label","wx_openid","weapp_openid","wx_unionid","ali_openid","douyin_openid","register_channel","register_type","login_ip","login_type","login_channel","login_count","login_time","last_visit_time","last_consum_time","sex","status","birthday","point","point_get","balance","balance_get","money","money_get","money_cash_outing","growth","growth_get","commission","commission_get","commission_cash_outing","is_member","member_time","create_time"], $where)->with(['users'])->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
/**
* 获取用户管理信息
* @param int $id
* @return array
*/
public function getInfo(int $id)
{
$field = 'member_id,member_no,pid,username,mobile,password,nickname,headimg,member_level,member_label,wx_openid,weapp_openid,wx_unionid,ali_openid,douyin_openid,register_channel,register_type,login_ip,login_type,login_channel,login_count,login_time,last_visit_time,last_consum_time,sex,status,birthday,point,point_get,balance,balance_get,money,money_get,money_cash_outing,growth,growth_get,commission,commission_get,commission_cash_outing,is_member,member_time,is_del,province_id,city_id,district_id,address,location,delete_time,create_time,update_time,created_by,created_role,updated_by,updated_role';
$info = $this->model->field($field)->where([['member_id', "=", $id]])->with(['users'])->findOrEmpty()->toArray();
$info['is_del'] = strval($info['is_del']);
return $info;
}
/**
* 添加用户管理
* @param array $data
* @return mixed
*/
public function add(array $data)
{
$res = $this->model->create($data);
return $res->member_id;
}
/**
* 用户管理编辑
* @param int $id
* @param array $data
* @return bool
*/
public function edit(int $id, array $data)
{
$this->model->where([['member_id', '=', $id]])->update($data);
return true;
}
/**
* 删除用户管理
* @param int $id
* @return bool
*/
public function del(int $id)
{
$model = $this->model->where([['member_id', '=', $id]])->find();
$res = $model->delete();
return $res;
}
public function getUsersAll(){
$usersModel = new Users();
return $usersModel->select()->toArray();
}
}

2
niucloud/addon/zhjw/app/validate/articles/Articles.php

@ -21,7 +21,6 @@ class Articles extends BaseValidate
protected $rule = [
'title' => 'require',
'content' => 'require',
'category' => 'require',
'publisher_id' => 'require',
'status' => 'require',
@ -29,7 +28,6 @@ class Articles extends BaseValidate
protected $message = [
'title.require' => ['common_validate.require', ['title']],
'content.require' => ['common_validate.require', ['content']],
'category.require' => ['common_validate.require', ['category']],
'publisher_id.require' => ['common_validate.require', ['publisher_id']],
'status.require' => ['common_validate.require', ['status']],

37
niucloud/addon/zhjw/app/validate/contracts/Contracts.php

@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\validate\contracts;
use core\base\BaseValidate;
/**
* 合同管理验证器
* Class Contracts
* @package addon\zhjw\app\validate\contracts
*/
class Contracts extends BaseValidate
{
protected $rule = [
'student_id' => 'require',
'title' => 'require',
];
protected $message = [
'student_id.require' => ['common_validate.require', ['student_id']],
'title.require' => ['common_validate.require', ['title']],
];
protected $scene = [
"add" => ['student_id', 'title', 'content', 'file_data', 'start_date', 'end_date', 'status'],
"edit" => ['student_id', 'title', 'content', 'file_data', 'start_date', 'end_date', 'status']
];
}

46
niucloud/addon/zhjw/app/validate/orders/Orders.php

@ -0,0 +1,46 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\validate\orders;
use core\base\BaseValidate;
/**
* 智慧教务-订单管理验证器
* Class Orders
* @package addon\zhjw\app\validate\orders
*/
class Orders extends BaseValidate
{
protected $rule = [
'student_id' => 'require',
'contract_id' => 'require',
'amount' => 'require|between:0.01,999999',
'order_type' => 'require',
'pay_type' => 'require',
'payment_status' => 'require',
];
protected $message = [
'student_id.require' => ['common_validate.require', ['student_id']],
'contract_id.require' => ['common_validate.require', ['contract_id']],
'amount.require' => ['common_validate.require', ['amount']],
'amount.between' => ['common_validate.between', ['amount','0.01','999999']],
'order_type.require' => ['common_validate.require', ['order_type']],
'pay_type.require' => ['common_validate.require', ['pay_type']],
'payment_status.require' => ['common_validate.require', ['payment_status']],
];
protected $scene = [
"add" => ['student_id', 'contract_id', 'amount', 'order_type', 'pay_type', 'payment_status', 'payment_time'],
"edit" => ['student_id', 'contract_id', 'amount', 'order_type', 'pay_type', 'payment_status', 'payment_time']
];
}

43
niucloud/addon/zhjw/app/validate/students/Students.php

@ -0,0 +1,43 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\validate\students;
use core\base\BaseValidate;
/**
* 学员管理验证器
* Class Students
* @package addon\zhjw\app\validate\students
*/
class Students extends BaseValidate
{
protected $rule = [
'name' => 'require',
'user_id' => 'require',
'have_study_time' => 'between:0,999999',
'end_study_time' => 'between:0,999999',
'status' => 'require',
];
protected $message = [
'name.require' => ['common_validate.require', ['name']],
'user_id.require' => ['common_validate.require', ['user_id']],
'have_study_time.between' => ['common_validate.between', ['have_study_time','0','999999']],
'end_study_time.between' => ['common_validate.between', ['end_study_time','0','999999']],
'status.require' => ['common_validate.require', ['status']],
];
protected $scene = [
"add" => ['name', 'user_id', 'have_study_time', 'end_study_time', 'emergency_contact', 'level', 'status'],
"edit" => ['name', 'user_id', 'have_study_time', 'end_study_time', 'emergency_contact', 'level', 'status']
];
}

49
niucloud/addon/zhjw/app/validate/users/Users.php

@ -0,0 +1,49 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\validate\users;
use core\base\BaseValidate;
/**
* 用户管理验证器
* Class Users
* @package addon\zhjw\app\validate\users
*/
class Users extends BaseValidate
{
protected $rule = [
'username' => 'require',
'mobile' => 'require',
'password' => 'require',
'nickname' => 'require',
'headimg' => 'require',
'sex' => 'require',
'status' => 'require',
'is_member' => 'require',
];
protected $message = [
'username.require' => ['common_validate.require', ['username']],
'mobile.require' => ['common_validate.require', ['mobile']],
'password.require' => ['common_validate.require', ['password']],
'nickname.require' => ['common_validate.require', ['nickname']],
'headimg.require' => ['common_validate.require', ['headimg']],
'sex.require' => ['common_validate.require', ['sex']],
'status.require' => ['common_validate.require', ['status']],
'is_member.require' => ['common_validate.require', ['is_member']],
];
protected $scene = [
"add" => ['member_no', 'pid', 'username', 'mobile', 'password', 'nickname', 'headimg', 'member_level', 'member_label', 'wx_openid', 'weapp_openid', 'wx_unionid', 'ali_openid', 'douyin_openid', 'register_channel', 'register_type', 'login_ip', 'login_type', 'login_channel', 'login_count', 'login_time', 'last_visit_time', 'last_consum_time', 'sex', 'status', 'birthday', 'point', 'point_get', 'balance', 'balance_get', 'money', 'money_get', 'money_cash_outing', 'growth', 'growth_get', 'commission', 'commission_get', 'commission_cash_outing', 'is_member', 'member_time', 'address'],
"edit" => ['member_no', 'pid', 'username', 'mobile', 'password', 'nickname', 'headimg', 'member_level', 'member_label', 'wx_openid', 'weapp_openid', 'wx_unionid', 'ali_openid', 'douyin_openid', 'register_channel', 'register_type', 'login_ip', 'login_type', 'login_channel', 'login_count', 'login_time', 'last_visit_time', 'last_consum_time', 'sex', 'status', 'birthday', 'point', 'point_get', 'balance', 'balance_get', 'money', 'money_get', 'money_cash_outing', 'growth', 'growth_get', 'commission', 'commission_get', 'commission_cash_outing', 'is_member', 'member_time', 'address']
];
}

2
niucloud/app/service/admin/sys/MenuService.php

@ -189,7 +189,7 @@ class MenuService extends BaseAdminService
$cache_name = 'menu_api_' . $status . '_' . $is_tree . '_' . $is_button;
// Cache::delete($cache_name);//重置菜单缓存-清空缓存-清空菜单缓存-当菜单不出现时打开本行注释,刷新页面后关闭注释
Cache::delete($cache_name);//重置菜单缓存-清空缓存-清空菜单缓存-当菜单不出现时打开本行注释,刷新页面后关闭注释
$menu_list = cache_remember(
$cache_name,

4
niucloud/runtime/cache/00/796846cef72c1934f657158416effa.php

@ -0,0 +1,4 @@
<?php
//000000000000
exit();?>
a:1:{i:0;s:121:"D:\DeveloperApp\phpstudy_pro\WWW\NiuCloud_ZhiHuiJiaoWu_Admin\niucloud\runtime\cache\25\380f91a13166c6be2a0a568ff0aba5.php";}

4
niucloud/runtime/cache/07/4bfa60510f475862a98e416426f451.php

@ -0,0 +1,4 @@
<?php
//000000003600
exit();?>
1

4
niucloud/runtime/cache/08/cd218d3b0adb213bef402dcf69ffe7.php

@ -0,0 +1,4 @@
<?php
//000000003600
exit();?>
1

4
niucloud/runtime/cache/09/f3d0b8f0a6d3610ef23e49d64d2f4f.php

@ -0,0 +1,4 @@
<?php
//000000000300
exit();?>
a:2:{s:9:"secretKey";s:16:"yxk6c6mxrww0d8ac";s:5:"point";O:27:"Fastknife\Domain\Vo\PointVo":2:{s:1:"x";i:257;s:1:"y";i:5;}}

4
niucloud/runtime/cache/0f/031b5cb7088c6004d3b5522558e3ee.php

@ -0,0 +1,4 @@
<?php
//000000003600
exit();?>
1

4
niucloud/runtime/cache/10/d14b034379d95ab08972c164bd0273.php

File diff suppressed because one or more lines are too long

4
niucloud/runtime/cache/13/0f87a1a4853b499cad67dae67fbbc5.php

@ -0,0 +1,4 @@
<?php
//000000003600
exit();?>
1

4
niucloud/runtime/cache/1a/fde0018bb1f6dadf6e9cc67514074e.php

@ -0,0 +1,4 @@
<?php
//000000003600
exit();?>
1

4
niucloud/runtime/cache/1f/893a713f7527421da280edd52452e1.php

@ -0,0 +1,4 @@
<?php
//000000003600
exit();?>
1

2
niucloud/runtime/cache/20/336a007c8134208722cf4e14270f07.php

File diff suppressed because one or more lines are too long

4
niucloud/runtime/cache/25/380f91a13166c6be2a0a568ff0aba5.php

@ -0,0 +1,4 @@
<?php
//000000000000
exit();?>
a:0:{}

2
niucloud/runtime/cache/2c/e25dcb326df717900650d384ad7cf0.php

@ -1,4 +1,4 @@
<?php
//000000000000
exit();?>
a:4:{i:0;s:121:"D:\DeveloperApp\phpstudy_pro\WWW\NiuCloud_ZhiHuiJiaoWu_Admin\niucloud\runtime\cache\20\336a007c8134208722cf4e14270f07.php";i:1;s:121:"D:\DeveloperApp\phpstudy_pro\WWW\NiuCloud_ZhiHuiJiaoWu_Admin\niucloud\runtime\cache\8d\4b55ce338f9b3a100a33ac8e8243e8.php";i:2;s:121:"D:\DeveloperApp\phpstudy_pro\WWW\NiuCloud_ZhiHuiJiaoWu_Admin\niucloud\runtime\cache\32\0a87fb2f5a7e9725055a2c99bd1e51.php";i:3;s:121:"D:\DeveloperApp\phpstudy_pro\WWW\NiuCloud_ZhiHuiJiaoWu_Admin\niucloud\runtime\cache\72\3ee2b5cca5d08bc4a333825c70f9c4.php";}
a:5:{i:0;s:121:"D:\DeveloperApp\phpstudy_pro\WWW\NiuCloud_ZhiHuiJiaoWu_Admin\niucloud\runtime\cache\8d\4b55ce338f9b3a100a33ac8e8243e8.php";i:1;s:121:"D:\DeveloperApp\phpstudy_pro\WWW\NiuCloud_ZhiHuiJiaoWu_Admin\niucloud\runtime\cache\20\336a007c8134208722cf4e14270f07.php";i:2;s:121:"D:\DeveloperApp\phpstudy_pro\WWW\NiuCloud_ZhiHuiJiaoWu_Admin\niucloud\runtime\cache\32\0a87fb2f5a7e9725055a2c99bd1e51.php";i:3;s:121:"D:\DeveloperApp\phpstudy_pro\WWW\NiuCloud_ZhiHuiJiaoWu_Admin\niucloud\runtime\cache\10\d14b034379d95ab08972c164bd0273.php";i:4;s:121:"D:\DeveloperApp\phpstudy_pro\WWW\NiuCloud_ZhiHuiJiaoWu_Admin\niucloud\runtime\cache\be\dce92610cb76bf49f7ad23a48eb701.php";}

2
niucloud/runtime/cache/32/0a87fb2f5a7e9725055a2c99bd1e51.php

File diff suppressed because one or more lines are too long

4
niucloud/runtime/cache/33/90cfdce4f303504facffc42620c48f.php

@ -0,0 +1,4 @@
<?php
//000000000000
exit();?>
a:1:{i:0;s:121:"D:\DeveloperApp\phpstudy_pro\WWW\NiuCloud_ZhiHuiJiaoWu_Admin\niucloud\runtime\cache\85\dff97d885b41077c47958d953c2dbd.php";}

4
niucloud/runtime/cache/3c/e760faa975bb7ccb960047660d6e14.php

@ -0,0 +1,4 @@
<?php
//000000003600
exit();?>
1

4
niucloud/runtime/cache/47/0f6e29f334d3244ee0749eb9b1a151.php

@ -0,0 +1,4 @@
<?php
//000000000000
exit();?>
-1

4
niucloud/runtime/cache/48/d6f2efc72c165d1f15db38570485f6.php

@ -0,0 +1,4 @@
<?php
//000000000000
exit();?>
-1

4
niucloud/runtime/cache/65/00bade063d7694b05ef06dcbf711a5.php

@ -0,0 +1,4 @@
<?php
//000000003600
exit();?>
1

4
niucloud/runtime/cache/69/75acdbf213ccfe0e2f593a09691914.php

@ -0,0 +1,4 @@
<?php
//000000000000
exit();?>
-1

4
niucloud/runtime/cache/69/a49e80c01c8ac6301283724181433f.php

@ -0,0 +1,4 @@
<?php
//000000003600
exit();?>
1

4
niucloud/runtime/cache/72/3ee2b5cca5d08bc4a333825c70f9c4.php

File diff suppressed because one or more lines are too long

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

Loading…
Cancel
Save