于宏哲PHP 1 year ago
parent
commit
404851fa09
  1. 54
      admin/src/addon/zhjw/api/feedback.ts
  2. 11
      admin/src/addon/zhjw/lang/zh-cn/feedback.feedback.json
  3. 13
      admin/src/addon/zhjw/lang/zh-cn/feedback.feedback_edit.json
  4. 175
      admin/src/addon/zhjw/views/feedback/feedback.vue
  5. 186
      admin/src/addon/zhjw/views/feedback/feedback_edit.vue
  6. 54
      niucloud/addon/zhjw/admin/api/feedback.ts
  7. 11
      niucloud/addon/zhjw/admin/lang/zh-cn/feedback.feedback.json
  8. 13
      niucloud/addon/zhjw/admin/lang/zh-cn/feedback.feedback_edit.json
  9. 175
      niucloud/addon/zhjw/admin/views/feedback/feedback.vue
  10. 182
      niucloud/addon/zhjw/admin/views/feedback/feedback_edit.vue
  11. 95
      niucloud/addon/zhjw/app/adminapi/controller/feedback/Feedback.php
  12. 76
      niucloud/addon/zhjw/app/model/feedback/Feedback.php
  13. 105
      niucloud/addon/zhjw/app/service/admin/feedback/FeedbackService.php
  14. 37
      niucloud/addon/zhjw/app/validate/feedback/Feedback.php

54
admin/src/addon/zhjw/api/feedback.ts

@ -0,0 +1,54 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- feedback
/**
*
* @param params
* @returns
*/
export function getFeedbackList(params: Record<string, any>) {
return request.get(`zhjw/feedback`, {params})
}
/**
*
* @param id id
* @returns
*/
export function getFeedbackInfo(id: number) {
return request.get(`zhjw/feedback/${id}`);
}
/**
*
* @param params
* @returns
*/
export function addFeedback(params: Record<string, any>) {
return request.post('zhjw/feedback', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @param params
* @returns
*/
export function editFeedback(params: Record<string, any>) {
return request.put(`zhjw/feedback/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @returns
*/
export function deleteFeedback(id: number) {
return request.delete(`zhjw/feedback/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithStudentsList(params: Record<string,any>){
return request.get('zhjw/students_all', {params})
}
// USER_CODE_END -- feedback

11
admin/src/addon/zhjw/lang/zh-cn/feedback.feedback.json

@ -0,0 +1,11 @@
{
"studentsId":"学员",
"studentsIdPlaceholder":"全部",
"content":"反馈内容",
"mailbox":"邮箱",
"addFeedback":"添加意见反馈",
"updateFeedback":"编辑意见反馈",
"feedbackDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

13
admin/src/addon/zhjw/lang/zh-cn/feedback.feedback_edit.json

@ -0,0 +1,13 @@
{
"studentsId":"学员",
"content":"反馈内容",
"images":"图片",
"mailbox":"邮箱",
"studentsIdPlaceholder":"请输入学员",
"contentPlaceholder":"请输入反馈内容",
"imagesPlaceholder":"请上传图片",
"mailboxPlaceholder":"请输入邮箱",
"addFeedback":"添加意见反馈",
"updateFeedback":"编辑意见反馈",
"feedbackDeleteTips":"确定要删除该意见反馈吗?"
}

175
admin/src/addon/zhjw/views/feedback/feedback.vue

@ -0,0 +1,175 @@
<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('addFeedback') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="feedbackTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('studentsId')" prop="students_id">
<el-select class="w-[280px]" v-model="feedbackTable.searchParam.students_id" clearable :placeholder="t('studentsIdPlaceholder')">
<el-option
v-for="(item, index) in studentsIdList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadFeedbackList()">{{ 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="feedbackTable.data" size="large" v-loading="feedbackTable.loading">
<template #empty>
<span>{{ !feedbackTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="students_id_name" :label="t('studentsId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="content" :label="t('content')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="mailbox" :label="t('mailbox')" min-width="120" :show-overflow-tooltip="true"/>
<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="feedbackTable.page" v-model:page-size="feedbackTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="feedbackTable.total"
@size-change="loadFeedbackList()" @current-change="loadFeedbackList" />
</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 { getFeedbackList, deleteFeedback, getWithStudentsList } from '@/addon/zhjw/api/feedback'
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 feedbackTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam:{
"students_id":""
}
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取意见反馈列表
*/
const loadFeedbackList = (page: number = 1) => {
feedbackTable.loading = true
feedbackTable.page = page
getFeedbackList({
page: feedbackTable.page,
limit: feedbackTable.limit,
...feedbackTable.searchParam
}).then(res => {
feedbackTable.loading = false
feedbackTable.data = res.data.data
feedbackTable.total = res.data.total
}).catch(() => {
feedbackTable.loading = false
})
}
loadFeedbackList()
const router = useRouter()
/**
* 添加意见反馈
*/
const addEvent = () => {
router.push('/feedback/feedback_edit')
}
/**
* 编辑意见反馈
* @param data
*/
const editEvent = (data: any) => {
router.push('/feedback/feedback_edit?id='+data.id)
}
/**
* 删除意见反馈
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('feedbackDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteFeedback(id).then(() => {
loadFeedbackList()
}).catch(() => {
})
})
}
const studentsIdList = ref([])
const setStudentsIdList = async () => {
studentsIdList.value = await (await getWithStudentsList({})).data
}
setStudentsIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadFeedbackList()
}
</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>

186
admin/src/addon/zhjw/views/feedback/feedback_edit.vue

@ -0,0 +1,186 @@
<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('studentsId')" prop="students_id">
<el-select class="input-width" v-model="formData.students_id" clearable :placeholder="t('studentsIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in studentsIdList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('content')" prop="content">
<el-input v-model="formData.content" type="textarea" rows="4" clearable :placeholder="t('contentPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('images')">
<upload-image v-model="formData.images" :limit="4"/>
</el-form-item>
<el-form-item :label="t('mailbox')" >
<el-input v-model="formData.mailbox" clearable :placeholder="t('mailboxPlaceholder')" 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 { getFeedbackInfo,addFeedback,editFeedback, getWithStudentsList } from '@/addon/zhjw/api/feedback';
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,
students_id: '',
content: '',
images: '',
mailbox: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const setFormData = async (id:number = 0) => {
Object.assign(formData, initialFormData)
const data = await (await getFeedbackInfo(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[]>([])
//
const studentsIdList = ref([] as any[])
const setStudentsIdList = async () => {
studentsIdList.value = await (await getWithStudentsList({})).data
}
setStudentsIdList()
//
const formRules = computed(() => {
return {
students_id: [
{ required: true, message: t('studentsIdPlaceholder'), trigger: 'blur' },
]
,
content: [
{ required: true, message: t('contentPlaceholder'), trigger: 'blur' },
]
,
images: [
{ required: true, message: t('imagesPlaceholder'), trigger: 'blur' },
]
,
mailbox: [
{ required: true, message: t('mailboxPlaceholder'), 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 ? editFeedback : addFeedback
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>

54
niucloud/addon/zhjw/admin/api/feedback.ts

@ -0,0 +1,54 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- feedback
/**
*
* @param params
* @returns
*/
export function getFeedbackList(params: Record<string, any>) {
return request.get(`zhjw/feedback`, {params})
}
/**
*
* @param id id
* @returns
*/
export function getFeedbackInfo(id: number) {
return request.get(`zhjw/feedback/${id}`);
}
/**
*
* @param params
* @returns
*/
export function addFeedback(params: Record<string, any>) {
return request.post('zhjw/feedback', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @param params
* @returns
*/
export function editFeedback(params: Record<string, any>) {
return request.put(`zhjw/feedback/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param id
* @returns
*/
export function deleteFeedback(id: number) {
return request.delete(`zhjw/feedback/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithStudentsList(params: Record<string,any>){
return request.get('zhjw/students_all', {params})
}
// USER_CODE_END -- feedback

11
niucloud/addon/zhjw/admin/lang/zh-cn/feedback.feedback.json

@ -0,0 +1,11 @@
{
"studentsId":"学员",
"studentsIdPlaceholder":"全部",
"content":"反馈内容",
"mailbox":"邮箱",
"addFeedback":"添加意见反馈",
"updateFeedback":"编辑意见反馈",
"feedbackDeleteTips":"确定要删除该数据吗?",
"startDate":"请选择开始时间",
"endDate":"请选择结束时间"
}

13
niucloud/addon/zhjw/admin/lang/zh-cn/feedback.feedback_edit.json

@ -0,0 +1,13 @@
{
"studentsId":"学员",
"content":"反馈内容",
"images":"图片",
"mailbox":"邮箱",
"studentsIdPlaceholder":"请输入学员",
"contentPlaceholder":"请输入反馈内容",
"imagesPlaceholder":"请上传图片",
"mailboxPlaceholder":"请输入邮箱",
"addFeedback":"添加意见反馈",
"updateFeedback":"编辑意见反馈",
"feedbackDeleteTips":"确定要删除该意见反馈吗?"
}

175
niucloud/addon/zhjw/admin/views/feedback/feedback.vue

@ -0,0 +1,175 @@
<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('addFeedback') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="feedbackTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('studentsId')" prop="students_id">
<el-select class="w-[280px]" v-model="feedbackTable.searchParam.students_id" clearable :placeholder="t('studentsIdPlaceholder')">
<el-option
v-for="(item, index) in studentsIdList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadFeedbackList()">{{ 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="feedbackTable.data" size="large" v-loading="feedbackTable.loading">
<template #empty>
<span>{{ !feedbackTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="students_id_name" :label="t('studentsId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="content" :label="t('content')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column prop="mailbox" :label="t('mailbox')" min-width="120" :show-overflow-tooltip="true"/>
<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="feedbackTable.page" v-model:page-size="feedbackTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="feedbackTable.total"
@size-change="loadFeedbackList()" @current-change="loadFeedbackList" />
</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 { getFeedbackList, deleteFeedback, getWithStudentsList } from '@/addon/zhjw/api/feedback'
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 feedbackTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam:{
"students_id":""
}
})
const searchFormRef = ref<FormInstance>()
//
const selectData = ref<any[]>([])
//
/**
* 获取意见反馈列表
*/
const loadFeedbackList = (page: number = 1) => {
feedbackTable.loading = true
feedbackTable.page = page
getFeedbackList({
page: feedbackTable.page,
limit: feedbackTable.limit,
...feedbackTable.searchParam
}).then(res => {
feedbackTable.loading = false
feedbackTable.data = res.data.data
feedbackTable.total = res.data.total
}).catch(() => {
feedbackTable.loading = false
})
}
loadFeedbackList()
const router = useRouter()
/**
* 添加意见反馈
*/
const addEvent = () => {
router.push('/feedback/feedback_edit')
}
/**
* 编辑意见反馈
* @param data
*/
const editEvent = (data: any) => {
router.push('/feedback/feedback_edit?id='+data.id)
}
/**
* 删除意见反馈
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('feedbackDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteFeedback(id).then(() => {
loadFeedbackList()
}).catch(() => {
})
})
}
const studentsIdList = ref([])
const setStudentsIdList = async () => {
studentsIdList.value = await (await getWithStudentsList({})).data
}
setStudentsIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadFeedbackList()
}
</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>

182
niucloud/addon/zhjw/admin/views/feedback/feedback_edit.vue

@ -0,0 +1,182 @@
<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('studentsId')" prop="students_id">
<el-radio-group v-model="formData.students_id" :placeholder="t('studentsIdPlaceholder')">
<el-radio
v-for="(item, index) in studentsIdList"
:key="index"
:label="item['id']">
{{ item['name'] }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('content')" prop="content">
<el-input v-model="formData.content" type="textarea" rows="4" clearable :placeholder="t('contentPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('images')">
<upload-image v-model="formData.images" />
</el-form-item>
<el-form-item :label="t('mailbox')" >
<el-input v-model="formData.mailbox" clearable :placeholder="t('mailboxPlaceholder')" 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 { getFeedbackInfo,addFeedback,editFeedback, getWithStudentsList } from '@/addon/zhjw/api/feedback';
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,
students_id: '',
content: '',
images: '',
mailbox: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const setFormData = async (id:number = 0) => {
Object.assign(formData, initialFormData)
const data = await (await getFeedbackInfo(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[]>([])
//
const studentsIdList = ref([] as any[])
const setStudentsIdList = async () => {
studentsIdList.value = await (await getWithStudentsList({})).data
}
setStudentsIdList()
//
const formRules = computed(() => {
return {
students_id: [
{ required: true, message: t('studentsIdPlaceholder'), trigger: 'blur' },
]
,
content: [
{ required: true, message: t('contentPlaceholder'), trigger: 'blur' },
]
,
images: [
{ required: true, message: t('imagesPlaceholder'), trigger: 'blur' },
]
,
mailbox: [
{ required: true, message: t('mailboxPlaceholder'), 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 ? editFeedback : addFeedback
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>

95
niucloud/addon/zhjw/app/adminapi/controller/feedback/Feedback.php

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

76
niucloud/addon/zhjw/app/model/feedback/Feedback.php

@ -0,0 +1,76 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\model\feedback;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
use addon\zhjw\app\model\students\Students;
/**
* 意见反馈模型
* Class Feedback
* @package addon\zhjw\app\model\feedback
*/
class Feedback extends BaseModel
{
use SoftDelete;
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
/**
* 模型名称
* @var string
*/
protected $name = 'feedback';
/**
* 定义软删除标记字段.
* @var string
*/
protected $deleteTime = 'is_deleted';
/**
* 定义软删除字段的默认值.
* @var int
*/
protected $defaultSoftDelete = 0;
/**
* 搜索器:意见反馈学员
* @param $value
* @param $data
*/
public function searchStudentsIdAttr($query, $value, $data)
{
if ($value) {
$query->where("students_id", $value);
}
}
public function students(){
return $this->hasOne(Students::class, 'id', 'students_id')->joinType('left')->withField('name,id')->bind(['students_id_name'=>'name']);
}
}

105
niucloud/addon/zhjw/app/service/admin/feedback/FeedbackService.php

@ -0,0 +1,105 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\service\admin\feedback;
use addon\zhjw\app\model\feedback\Feedback;
use addon\zhjw\app\model\students\Students;
use core\base\BaseAdminService;
/**
* 意见反馈服务层
* Class FeedbackService
* @package addon\zhjw\app\service\admin\feedback
*/
class FeedbackService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new Feedback();
}
/**
* 获取意见反馈列表
* @param array $where
* @return array
*/
public function getPage(array $where = [])
{
$field = 'id,students_id,content,images,mailbox,create_time,is_deleted';
$order = 'id desc';
$search_model = $this->model->withSearch(["students_id"], $where)->with(['students'])->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
/**
* 获取意见反馈信息
* @param int $id
* @return array
*/
public function getInfo(int $id)
{
$field = 'id,students_id,content,images,mailbox,create_time,is_deleted';
$info = $this->model->field($field)->where([['id', "=", $id]])->with(['students'])->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 getStudentsAll(){
$studentsModel = new Students();
return $studentsModel->select()->toArray();
}
}

37
niucloud/addon/zhjw/app/validate/feedback/Feedback.php

@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\zhjw\app\validate\feedback;
use core\base\BaseValidate;
/**
* 意见反馈验证器
* Class Feedback
* @package addon\zhjw\app\validate\feedback
*/
class Feedback extends BaseValidate
{
protected $rule = [
'students_id' => 'require',
'content' => 'require',
];
protected $message = [
'students_id.require' => ['common_validate.require', ['students_id']],
'content.require' => ['common_validate.require', ['content']],
];
protected $scene = [
"add" => ['students_id', 'content', 'images', 'mailbox'],
"edit" => ['students_id', 'content', 'images', 'mailbox']
];
}
Loading…
Cancel
Save