Commit d6457ba4 authored by daniel's avatar daniel

fix(feedback): feedback联调完成

parent 9b63338f
......@@ -30,9 +30,9 @@
WHERE id = #{id}
</update>
<delete id="delete" parameterType="java.lang.Integer">
DELETE FROM feedback_category WHERE id = #{id}
</delete>
<update id="delete" parameterType="java.lang.Integer">
UPDATE feedback_category SET del_flag = 1 WHERE id = #{id}
</update>
<select id="selectById" parameterType="java.lang.Integer" resultType="com.dlbridge.jadp.plugins.cmpt.dao.model.FeedbackCategory">
SELECT * FROM feedback_category WHERE id = #{id}
......@@ -53,7 +53,7 @@
<if test="isActive != null">
AND is_active = #{isActive}
</if>
AND del_flag = 0
AND del_flag = 0 order by sort_order asc
</where>
</select>
......
......@@ -2,7 +2,7 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dlbridge.jadp.plugins.cmpt.dao.mapper.FeedbackMapper">
<insert id="insert" parameterType="com.dlbridge.jadp.plugins.cmpt.dao.model.Feedback">
INSERT INTO feedback (user_id, category_id, content, contact_info, feedback_image_url, current_status, admin_notes, resolution_result,feedback_no, resolve_image_url, del_flag,cmpt_id)
INSERT INTO feedback (user_id, category_id, content, contact_info,feedback_no, feedback_image_url, current_status, admin_notes, resolution_result, resolve_image_url, del_flag,cmpt_id)
VALUES (#{userId}, #{categoryId}, #{content}, #{contactInfo},#{feedbackNo}, #{feedbackImageUrl}, #{currentStatus}, #{adminNotes}, #{resolutionResult}, #{resolveImageUrl}, 0,#{cmptId})
</insert>
......@@ -36,6 +36,9 @@
<if test="resolveImageUrl != null">
resolve_image_url = #{resolveImageUrl},
</if>
<if test="resolvedAt != null">
resolved_at = #{resolvedAt},
</if>
<if test="delFlag != null">
del_flag = #{delFlag}
</if>
......@@ -43,9 +46,11 @@
WHERE id = #{id}
</update>
<delete id="delete" parameterType="java.lang.Integer">
DELETE FROM feedback WHERE id = #{id}
</delete>
<update id="delete" parameterType="java.lang.Integer">
UPDATE feedback
SET del_flag = 1
WHERE id = #{id}
</update>
<select id="selectById" parameterType="java.lang.Integer" resultType="com.dlbridge.jadp.plugins.cmpt.dao.model.Feedback">
SELECT * FROM feedback WHERE id = #{id}
......@@ -63,7 +68,7 @@
<if test="categoryId != null">
AND category_id = #{categoryId}
</if>
<if test="feedbackNo != null">
<if test="feedbackNo != null and feedbackNo !=''">
AND feedback_no = #{feedbackNo}
</if>
<if test="currentStatus != null and currentStatus != ''">
......
......@@ -2,10 +2,13 @@ package com.dlbridge.jadp.plugins.cmpt.dao.model;
import com.dlbridge.jadp.common.persistence.JaapRecord;
import com.dlbridge.jadp.plugins.partner.bean.BagDelivery;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
......@@ -16,18 +19,32 @@ import java.util.Date;
@Accessors(chain = true)
public class Feedback extends JaapRecord<BagDelivery> {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "反馈编号,后台自主生成", notes = "反馈编号,后台自主生成")
private String feedbackNo; // 反馈编号,后台自主生成
@ApiModelProperty(value = "用户ID", notes = "用户ID")
private Integer userId;
@ApiModelProperty(value = "赛事ID", notes = "赛事ID")
private Integer cmptId; // 赛事id
@ApiModelProperty(value = "反馈类别ID", notes = "反馈类别ID")
private Integer categoryId; // 反馈类别ID
@ApiModelProperty(value = "问题描述内容", notes = "问题描述内容")
private String content; // 问题描述内容
@ApiModelProperty(value = "联系方式(手机/邮箱", notes = "联系方式(手机/邮箱")
private String contactInfo; // 联系方式(手机/邮箱
@ApiModelProperty(value = "反馈图片URL,多张以逗号分隔", notes = "反馈图片URL,多张以逗号分隔")
private String feedbackImageUrl; // 反馈图片URL,多张以逗号分隔
private String currentStatus; // 当前状态 'pending','processing','resolved'(待处理/处理中/已解决)
@ApiModelProperty(value = "当前状态0,1,2(待处理/处理中/已解决) 当前状态:待处理/处理中/已解决", notes = "当前状态0,1,2(待处理/处理中/已解决) 当前状态:待处理/处理中/已解决")
private Integer currentStatus; // 当前状态0,1,2(待处理/处理中/已解决) 当前状态:待处理/处理中/已解决
@ApiModelProperty(value = "管理员备注", notes = "管理员备注")
private String adminNotes; // 管理员备注
@ApiModelProperty(value = "解决结果", notes = "解决结果")
private String resolutionResult; // 解决结果
@ApiModelProperty(value = "解决图片URL,多张以逗号分隔", notes = "解决图片URL,多张以逗号分隔")
private String resolveImageUrl; // 解决图片URL,多张以逗号分隔
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date resolvedAt; // 解决时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdAt;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updatedAt;
}
......@@ -4,7 +4,9 @@ package com.dlbridge.jadp.plugins.cmpt.dao.model;
import com.dlbridge.jadp.common.persistence.JaapRecord;
import com.dlbridge.jadp.plugins.partner.bean.BagDelivery;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
......@@ -17,11 +19,20 @@ import java.util.Date;
@Accessors(chain = true)
public class FeedbackCategory extends JaapRecord<BagDelivery> {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户id", notes = "用户id")
private Integer userId;
@ApiModelProperty(value = "赛事id", notes = "赛事id")
private Integer cmptId; // 赛事id
@ApiModelProperty(value = "分类名称", notes = "分类名称")
private String name; // 分类名称
@ApiModelProperty(value = "排序顺序", notes = "排序顺序")
private Integer sortOrder; // 排序顺序
@ApiModelProperty(value = "是否启用", notes = "是否启用")
private Integer isActive; // 是否启用
@ApiModelProperty(value = "创建时间", notes = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdAt;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新时间", notes = "更新时间")
private Date updatedAt;
}
......@@ -10,4 +10,5 @@ public class FeedbackQueryDTO extends PageDTO {
private Integer categoryId;
private Integer cmptId;
private String currentStatus;
private String feedbackNo;
}
......@@ -82,7 +82,7 @@
<div class="page-content d-flex align-items-stretch main-body">
<jsp:include page="../common/menu.jsp"></jsp:include>
<div id="app" class="flex-1" v-cloak>
<n-config-provider>
<n-config-provider :locale="locale" :date-locale="dateLocale">
<n-modal-provider>
<n-message-provider>
<n-notification-provider>
......@@ -94,92 +94,189 @@
</div>
</div>
<script type="text/x-template" id="my-app">
<n-space vertical>
<n-space vertical >
<!-- 顶部的搜索框 -->
<n-card :bordered="false">
<div class="w-full flex flex-row items-center gap-x-2">
<div style="width: 200px">
<n-tabs type="segment" @update:value="updateStatus" :value="status" animated pane-style="padding:0;">
<n-tab-pane v-for="item in statusOptions" :name="item.value" :tab="item.name"></n-tab-pane>
</n-tabs>
<n-card :bordered="false">
<div class="w-full flex flex-row items-center gap-x-2">
<div style="width: 200px">
<n-tabs type="segment" @update:value="updateStatus" :value="status" animated pane-style="padding:0;">
<n-tab-pane v-for="item in [{name:'全部',value:''},...statusOptions]" :name="item.value" :tab="item.name"></n-tab-pane>
</n-tabs>
</div>
<div class="ml-auto"><n-input placeholder="请输入搜索内容" /></div>
<n-button type="primary">
搜索
</n-button>
<n-button type="primary" @click="addFeedBack">
新增测试
</n-button>
</div>
</n-card>
<!-- 搜索框 -->
<div class="w-full flex flex-row items-start gap-x-3">
<div class="bg-white flex flex-col gap-y-2 p-3">
<h4 class="flex flex-row items-center justify-between w-full">
分类列表
<n-button type="primary" @click="onEditCategory(null)" size="tiny">
新增
</n-button>
</h4>
<div v-for="(item,index) in feedbackCategories" :key="item.value" class="flex rounded-sm flex-row items-center gap-x-1">
<span class="py-1 px-4 rounded-sm animate-fade-in" :class="[categoryIndex===index?'bg-primary text-white':'']" class="flex-1" @click="changeCategory(index)"> {{item.name}}
</span>
<n-tag round :bordered="false" size="small" :type="item.isActive?'success':'error'" class="cursor-pointer">
{{item.isActive?'开启':'关闭'}}
</n-tag>
<ion-icon @click="onEditCategory(item)" class="cursor-pointer" name="create-outline"></ion-icon>
<n-popconfirm
@positive-click="onDelCategory(item)"
>
<template #trigger>
<ion-icon class="text-red cursor-pointer" name="trash-outline"></ion-icon>
</template>
是否删除该分类
</n-popconfirm>
</div>
</div>
<div class="flex-1">
<n-data-table :columns="columns" :loading="loading" :data="feedbacks" :pagination="pagination"
:bordered="false" @update:page="handlePageChange"/>
</div>
</div>
<div class="ml-auto"><n-input placeholder="请输入搜索内容" /></div>
<n-button type="primary">搜索</n-button>
</div>
</n-card>
<!-- 搜索框 -->
<div class="w-full flex flex-row items-start gap-x-3">
<div class="bg-white flex flex-col gap-y-2 p-3">
<h4 >
分类列表
<n-button type="primary" @click="onEditCategory(null)" size="tiny">
新增
</n-button>
</h4>
<div :class="[categoryIndex===index?'bg-primary text-white':'']" v-for="(item,index) in feedbackCategories" :key="item.value" class="flex py-1 px-2 rounded-sm flex-row items-center gap-x-1">
<span class="flex-1" @click="changeCategory(index)"> {{item.name}}
</span>
<ion-icon @click="onEditCategory(item)" class="cursor-pointer" name="create-outline"></ion-icon>
<ion-icon @click="onDelCategory" class="text-red cursor-pointer" name="trash-outline"></ion-icon>
</div>
</div>
<div class="flex-1">
<n-data-table :columns="columns" :data="data" :pagination="pagination"
:bordered="false" />
</div>
</div>
<n-modal :loading="loading" style="width: 400px" :title="categoryFormValue.id?'编辑分类':'新增分类'"
preset="card"
draggable v-model:show="showCategoryModal" >
<n-form
ref="categoryFormRef"
:model="categoryFormValue"
:rules="categoryRules"
size="small"
label-placement="left"
label-width="auto"
>
<n-form-item label="分类名" path="name">
<n-input v-model:value="categoryFormValue.name" placeholder="请输入分类名" />
</n-form-item>
<n-form-item label="排序" path="sortOrder">
<n-input-number v-model:value="categoryFormValue.sortOrder" placeholder="请输入排序" />
</n-form-item>
<n-form-item label="状态" path="isActive">
<n-switch
:checked-value="1"
:unchecked-value="0"
v-model:value="categoryFormValue.isActive"
<n-modal :mask-closable="false" :loading="loading" style="width: 400px" :title="categoryFormValue.id?'编辑分类':'新增分类'"
preset="card"
draggable v-model:show="showCategoryModal" >
<n-form
ref="categoryFormRef"
:model="categoryFormValue"
:rules="categoryRules"
size="small"
label-placement="left"
label-width="auto"
>
<template #checked>
开启
</template>
<template #unchecked>
关闭
</template>
</n-switch>
</n-form-item>
</n-form>
<template #footer>
<div class="flex gap-x-2 flex-row items-center" >
<n-button :loading="loading" class="flex-1" @click="onCategoryCancel">
取消
</n-button>
<n-button :loading="loading" class="flex-1" type='primary' @click="onCategorySubmit">
保存
</n-button>
</div>
</template>
</n-modal>
</n-space>
<n-form-item label="分类名" path="name">
<n-input v-model:value="categoryFormValue.name" placeholder="请输入分类名" />
</n-form-item>
<n-form-item label="排序" path="sortOrder">
<n-input-number v-model:value="categoryFormValue.sortOrder" placeholder="请输入排序" />
</n-form-item>
<n-form-item label="状态" path="isActive">
<n-switch
:checked-value="1"
:unchecked-value="0"
v-model:value="categoryFormValue.isActive"
>
<template #checked>
开启
</template>
<template #unchecked>
关闭
</template>
</n-switch>
</n-form-item>
</n-form>
<template #footer>
<div class="flex gap-x-2 flex-row items-center" >
<n-button class="flex-1" :loading="loading" @click="onCategoryCancel">
取消
</n-button>
<n-button class="flex-1"
:loading="loading" type='primary' @click="onCategorySubmit">
保存
</n-button>
</div>
</template>
</n-modal>
<n-modal :mask-closable="false" :loading="loading" style="width: 600px" :title="feedbackFormValue.id?'处理反馈':'新增反馈'"
preset="card"
draggable v-model:show="showFeedbackModal" >
<n-form
ref="feedbackFormRef"
:model="feedbackFormValue"
:rules="feedbackRules"
size="small"
label-placement="left"
label-width="auto"
>
<n-form-item label="反馈图片" path="feedbackImageUrl">
<n-upload
:action="uploadUrl"
:disabled="true"
v-model:file-list="fileList"
list-type="image-card"
>
点击上传
</n-upload>
</n-form-item>
<n-form-item label="联系信息" path="contactInfo">
<n-input :disabled="true" v-model:value="feedbackFormValue.contactInfo" placeholder="请输入联系信息" />
</n-form-item>
<n-form-item label="反馈内容" path="content">
<n-input :disabled="true" type="textarea" v-model:value="feedbackFormValue.content" placeholder="请输入反馈内容" />
</n-form-item>
<!-- 后台填写的内容 -->
<n-form-item label="处理图片" path="resolveImageUrl">
<n-upload
:action="uploadUrl"
v-model:file-list="resultFileList"
list-type="image-card"
@finish="uploadFinish"
>
点击上传
</n-upload>
</n-form-item>
<n-form-item label="处理结果" path="resolutionResult">
<n-input clearable type="textarea" v-model:value="feedbackFormValue.resolutionResult" placeholder="请输入处理结果" />
</n-form-item>
<n-form-item label="管理员备注" path="adminNotes">
<n-input clearable type="textarea" v-model:value="feedbackFormValue.adminNotes" placeholder="请输入管理员备注" />
</n-form-item>
<n-form-item label="处理时间" path="resolvedAt">
<n-date-picker value-format="yyyy-MM-dd HH:mm:ss" date-format="yyyy-MM-dd HH:mm:ss" class="w-full" :value="feedbackFormValue.resolvedAt" type="datetime" clearable @update:formatted-value="updateFormattedValue" />
</n-form-item>
<n-form-item label="处理状态" path="currentStatus">
<n-radio-group v-model:value="feedbackFormValue.currentStatus" name="radiogroup">
<n-space>
<n-radio v-for="statusOpt in statusOptions" :key="statusOpt.value" :value="statusOpt.value">
{{ statusOpt.name }}
</n-radio>
</n-space>
</n-radio-group>
</n-form-item>
</n-form>
<template #footer>
<div class="flex gap-x-2 flex-row items-center" >
<n-button class="flex-1" :loading="loading" @click="onFeedbackCancel">
取消
</n-button>
<n-button class="flex-1"
:loading="loading" type='primary' @click="onFeedbackSubmit">
保存
</n-button>
</div>
</template>
</n-modal>
<n-modal
v-model:show="showFeedbackDelModal"
preset="dialog"
title="确认"
content="你确定要删除该反馈吗?"
positive-text="确认"
negative-text="算了"
@positive-click="deleteFeedback"
/>
</n-space>
</script>
<script>
const { createApp, defineComponent, reactive, ref, onMounted } = Vue;
const { useMessage, useNotification } = naive
const BASE_URL = window.location.origin + '/gk/feedback-category'
const { createApp, defineComponent, reactive, ref, onMounted, h } = Vue;
const { useMessage, useNotification, dateZhCN, NButton, NTag, zhCN, NSpace, NImageGroup, NImage, NText } = naive
// 添加全局 loading 指令
const FC_BASE_URL = window.location.origin + '/gk/feedback-category'
const F_BASE_URL = window.location.origin + '/gk/feedback'
const uploadUrl = window.location.origin + '/api-common/v1/upload?folder=' + 'gk/feedback' + '&cmptId=' + getCId()
// to 方法,封装try catch
const to = async (
promise,
......@@ -225,6 +322,8 @@
// 分类切换,刷新table
const changeCategory = (index) => {
categoryIndex.value = index
pagination.value.page = 1
getFeedBacks()
}
// 编辑分类
const onEditCategory = (item) => {
......@@ -238,8 +337,26 @@
showCategoryModal.value = true
}
// 删除分类
const onDelCategory = (item) => {
console.log(item)
const onDelCategory = async (item) => {
loading.value = true
const messageReactive = message.loading('删除中...', {
duration: 0
})
// 发起请求
const [err, data] = await to(fetch(FC_BASE_URL + '/' + item.id, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
}).then(res => res.json()))
loading.value = false
messageReactive.destroy()
if (data.code === 200) {
message.success('删除成功')
getCategories()
} else {
message.error(data.msg)
}
}
// 获取分类列表
const getCategories = async () => {
......@@ -248,8 +365,9 @@
pageSize: 20,
cmptId: getCId()
}
loading.value = true;
// 发起请求
const [err, data] = await to(fetch(BASE_URL + '/page', {
const [err, data] = await to(fetch(FC_BASE_URL + '/page', {
method: "POST",
headers: {
'Content-Type': 'application/json'
......@@ -260,6 +378,7 @@
if (data.code === 200) {
feedbackCategories.value = data.content.content
showCategoryModal.value = false
getFeedBacks()
} else {
message.error(data.msg)
}
......@@ -277,8 +396,11 @@
cmptId: getCId()
}
loading.value = true
const messageReactive = message.loading(categoryFormValue.id ? '数据更新中...' : '数据添加中...', {
duration: 0
})
// 发起请求
const [err, data] = await to(fetch(BASE_URL, {
const [err, data] = await to(fetch(FC_BASE_URL, {
method: method,
headers: {
'Content-Type': 'application/json'
......@@ -286,6 +408,7 @@
body: JSON.stringify(params)
}).then(res => res.json()))
loading.value = false
messageReactive.destroy()
if (data.code === 200) {
message.success('操作成功')
showCategoryModal.value = false
......@@ -305,42 +428,345 @@
showCategoryModal.value = false
}
/***----------------分类相关 end-----------------*/
/***---------------- 反馈相关 start-----------------*/
const columns = [{
title: '选手反馈',
key: 'content',
render: (row) => {
// 用h函数实现
const images = row.feedbackImageUrl?.split(',') ?? []
return h(NSpace, {
vertical: true,
}, [
h(NText, {}, "反馈编号:" + row.feedbackNo),
h(NText, {}, "选手反馈:" + row.content),
h(NText, {}, "反馈时间:" + row.createdAt),
h(NImageGroup, {}, [
...images.map((img) => h(NImage, {
height: "100",
src: img
}))
]),
])
}
},
{
title: '组委会处理',
key: 'resolutionResult',
render: (row) => {
const images = row.resolveImageUrl?.split(',') ?? []
return h(NSpace, {
vertical: true,
}, [
h(NText, {}, "处理结果:" + (row.resolutionResult ?? '--')),
h(NText, {}, "组委会备注:" + (row.adminNotes ?? '--')),
h(NText, {}, "处理时间:" + (row.resolvedAt ?? '--')),
h(NImageGroup, {}, [
...images.map((img) => h(NImage, {
height: "100",
src: img
}))
]),
])
}
},
{
title: '处理状态',
key: 'currentStatus',
width: 100,
render: (row) => {
const status = statusOptions.find(v => row.currentStatus === v.value)
return h(NTag, {
type: status.type
}, status.name)
}
},
{
title: '操作',
key: 'actions',
width: 150,
align: 'center',
render: (row) => {
// 两个按钮,一个 编辑 一个 删除
return h(NSpace, {}, [
h(NButton, {
type: 'primary',
size: 'small',
onClick: () => {
// 编辑
editFeedback(row)
}
}, '编辑'),
h(NButton, {
type: 'error',
size: 'small',
onClick: () => {
// 删除
// deleteFeedback(row)
feedback.value = row
showFeedbackDelModal.value = true
}
}, '删除')
])
}
}]
const pagination = ref({ pageSize: 20, page: 1 })
// 文件列表
const fileList = ref([])
// 结果列表
const resultFileList = ref([])
// 反馈弹框
const showFeedbackModal = ref(false)
// 删除反馈
const showFeedbackDelModal = ref(false)
const feedback = ref()
// 反馈的formRef
const feedbackFormRef = ref(null)
// 反馈的数据列表
const feedbacks = ref([])
// 反馈表单
const feedbackFormValue = reactive({
id: undefined,
feedbackImageUrl: '',
contactInfo: '',
content: '',
currentStatus: 0,
adminNotes: '', // 管理员备注
resolutionResult: '', // 解决结果
resolveImageUrl: '', // 解决图片URL,多张以逗号分隔
resolvedAt: undefined // 解决时间
})
// 反馈的校验规则
feedbackRules = {
resolutionResult: {
required: true,
message: '请输入解决结果',
trigger: 'blur'
}
}
// 状态类型
const statusOptions = [
{
name: '未处理',
value: 'pending'
value: 0,
type: 'warning'
},
{
name: '处理中',
value: 'processing'
value: 1,
type: 'info'
},
{
name: '已处理',
value: 'resolved'
value: 2,
type: 'success'
}
]
// 当前状态
const status = ref(statusOptions[0].value)
const status = ref('')
// 状态更新
const updateStatus = (value) => {
pagination.value.page = 1
status.value = value
getFeedBacks()
}
// 新增反馈
const addFeedBack = () => {
showFeedbackModal.value = true
}
const notify = (type) => {
notification[type]({
content: 'What to say?',
meta: 'I don\'t know',
duration: 2500,
keepAliveOnHover: true
// 上传完成
const uploadFinish = ({
file,
event
}) => {
const response = JSON.parse(event?.target?.response)
file.url = response.content
return file
}
// 重置form数据
const resetFeedbackValue = () => {
feedbackFormValue.id = undefined
feedbackFormValue.feedbackImageUrl = ''
feedbackFormValue.contactInfo = ''
feedbackFormValue.content = ''
feedbackFormValue.currentStatus = 0
feedbackFormValue.adminNotes = ''
feedbackFormValue.resolutionResult = ''
feedbackFormValue.resolveImageUrl = ''
feedbackFormValue.resolvedAt = undefined
}
// 删除反馈
const deleteFeedback = () => {
if (!feedback.value) {
showFeedbackDelModal.value = false
return
}
loading.value = true
const messageReactive = message.loading('删除中...', {
duration: 0
})
// 发起请求
fetch(F_BASE_URL + '/' + feedback.value.id, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
}).then(res => res.json()).then(data => {
if (data.code === 200) {
message.success('删除成功')
getFeedBacks()
} else {
message.error(data.msg)
}
}).finally(() => {
loading.value = true
messageReactive.destroy()
showFeedbackDelModal.value = false
})
}
// 编辑反馈
const editFeedback = (feedback) => {
resetFeedbackValue()
showFeedbackModal.value = true
feedbackFormValue.id = feedback.id
feedbackFormValue.feedbackImageUrl = ''
feedbackFormValue.contactInfo = feedback.contactInfo
feedbackFormValue.content = feedback.content
feedbackFormValue.currentStatus = feedback.currentStatus
feedbackFormValue.adminNotes = feedback.adminNotes
feedbackFormValue.resolutionResult = feedback.resolutionResult
feedbackFormValue.resolvedAt = feedback.resolvedAt
// 图片的处理
if (feedback?.resolveImageUrl) {
resultFileList.value = feedback.resolveImageUrl.split(',').map(v => ({
url: v,
status: 'finished',
name: v.split('/').pop(),
id: v,
uid: v
}))
}
if (feedback?.feedbackImageUrl) {
fileList.value = feedback.feedbackImageUrl.split(',').map(v => ({
url: v,
status: 'finished',
name: v.split('/').pop(),
id: v,
uid: v
}))
}
showFeedbackModal.value = true
}
// 取消操作
const onFeedbackCancel = () => {
showFeedbackModal.value = false
resetFeedbackValue()
}
// 提交
const onFeedbackSubmit = (e) => {
e.preventDefault()
feedbackFormRef.value?.validate(async (errors) => {
if (errors) return message.error('请检查表单是否填写完整')
const method = feedbackFormValue.id ? 'PUT' : 'POST'
// 使用fetch发起请求
const params = {
...feedbackFormValue,
categoryId: feedbackCategories.value[categoryIndex.value].id,
cmptId: getCId(),
resolveImageUrl: resultFileList.value.map(v => v.url).join()
}
// 移除这个参数
delete params.content
delete params.contactInfo
delete params.feedbackImageUrl
loading.value = true
const messageReactive = message.loading(feedbackFormValue.id ? '数据更新中...' : '数据添加中...', {
duration: 0
})
// 发起请求
const [err, data] = await to(fetch(F_BASE_URL, {
method: method,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => res.json()))
loading.value = false
messageReactive.destroy()
if (data.code === 200) {
message.success('操作成功')
showFeedbackModal.value = false
resetFeedbackValue()
getCategories()
} else {
message.error(data.msg)
}
})
}
// 获取反馈分页列表
const getFeedBacks = async () => {
loading.value = true
// 发起请求
const [err, data] = await to(fetch(F_BASE_URL + '/page', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
cmptId: getCId(),
currentStatus: status.value ? undefined : status.value,
pageNum: pagination.value.page,
pageSize: pagination.value.pageSize,
categoryId: feedbackCategories.value[categoryIndex.value].id
})
}).then(res => res.json()))
loading.value = false
if (data.code === 200) {
feedbacks.value = data.content.content
} else {
message.error(data.msg)
}
}
// 分页切换
const handlePageChange = (page) => {
pagination.value.page = page
getFeedBacks()
}
// 日期处理
const updateFormattedValue = (val) => {
feedbackFormValue.resolvedAt = val
}
/***---------------- 反馈相关 end -----------------*/
onMounted(() => {
getCategories()
})
return {
// 反馈相关
addFeedBack,
statusOptions,
status,
updateStatus,
showFeedbackModal,
feedbackFormRef,
feedbackFormValue,
onFeedbackCancel,
onFeedbackSubmit,
fileList,
feedbacks,
pagination,
handlePageChange,
columns,
deleteFeedback,
editFeedback,
showFeedbackDelModal,
feedbackRules,
updateFormattedValue,
resultFileList,
// 反馈分类相关
feedbackCategories,
categoryIndex,
changeCategory,
......@@ -352,35 +778,21 @@
showCategoryModal,
categoryRules,
onCategorySubmit,
// 公共数据
uploadUrl,
uploadFinish,
loading,
data: [
{ no: 3, title: 'Wonderwall', length: '4:18' },
{ no: 4, title: 'Don\'t Look Back in Anger', length: '4:48' },
{ no: 12, title: 'Champagne Supernova', length: '7:27' }
],
pagination: ref({ pageSize: 5 }),
columns: [{
title: 'No',
key: 'no'
},
{
title: 'Title',
key: 'title'
},
{
title: 'Length',
key: 'length'
},
{
title: 'Action',
key: 'actions'
}],
}
}
})
const app = Vue.createApp({})
const app = Vue.createApp({
setup() {
return {
locale: zhCN,
dateLocale: dateZhCN
}
}
})
app.component('my-app', MyApp)
app.use(naive)
app.mount('#app')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment