ソースを参照

feat: 投诉建议暂存

touchitvoid 2 年 前
コミット
b27374811f

+ 20 - 1
src/router/config.tsx

@@ -94,6 +94,8 @@ const FixOrderDetail = lazy(() => import('../views/Fix/order-detail'))
 
 // 投诉相关
 const Complaint = lazy(() => import('../views/Complaint/index'))
+const ComplaintHandle = lazy(() => import('../views/Complaint/handle'))
+const ComplaintReturnVisit = lazy(() => import('../views/Complaint/return-visit'))
 const ComplaintDetail = lazy(() => import('../views/Complaint/order-detail'))
 
 export const Wrapper = (Component) => (props) => {
@@ -423,7 +425,6 @@ export const routes: any = [
     title: '投诉建议',
     path: '/admin/complaint',
     exact: true,
-    component: Wrapper(Complaint),
     children: [
       {
         title: '投诉建议详情',
@@ -432,6 +433,24 @@ export const routes: any = [
         component: Wrapper(ComplaintDetail),
         hideInMenu: true
       },
+      {
+        title: '投诉录入',
+        path: '/admin/complaint',
+        exact: true,
+        component: Wrapper(Complaint),
+      },
+      {
+        title: '投诉受理',
+        path: '/admin/complaint/handle',
+        exact: true,
+        component: Wrapper(ComplaintHandle),
+      },
+      {
+        title: '投诉回访',
+        path: '/admin/complaint/return-visit',
+        exact: true,
+        component: Wrapper(ComplaintReturnVisit),
+      },
     ]
   },
   {

+ 28 - 0
src/services/complaint.ts

@@ -14,3 +14,31 @@ export const GetComplaintInfo = () => request({
   url: '/suggestion/order/info',
   method: 'get'
 })
+
+// 派单 /api/v1/suggestion/order/send
+export const ComplaintOrderSend = data => request({
+  url: '/suggestion/order/send',
+  method: 'put',
+  data
+})
+
+// 退单
+export const ComplaintOrderRefund = data => request({
+  url: '/suggestion/order/back',
+  method: 'put',
+  data
+})
+
+// 结单
+export const ComplaintOrderFinish = data => request({
+  url: '/suggestion/order/finish',
+  method: 'put',
+  data
+})
+
+// 回访
+export const ComplaintOrderReturnVisit = data => request({
+  url: '/suggestion/order/return_visit',
+  method: 'put',
+  data
+})

+ 1 - 1
src/services/fix.ts

@@ -36,7 +36,7 @@ export const FixOrderFinish = data => request({
   data
 })
 
-// 结单 /api/v1/repair/order/return_visit
+// 回访 /api/v1/repair/order/return_visit
 export const FixOrderReturnVisit = data => request({
   url: '/repair/order/return_visit',
   method: 'put',

+ 211 - 0
src/views/Complaint/handle.tsx

@@ -0,0 +1,211 @@
+import React from 'react'
+import type { ActionType } from '@ant-design/pro-table'
+import ProTable from '@ant-design/pro-table'
+import { Button, Modal, Form, Input, message, Select, Upload } from 'antd'
+import { withRouter } from 'react-router-dom'
+import {
+  ComplaintApi,
+  ComplaintOrderSend,
+  ComplaintOrderRefund,
+  ComplaintOrderFinish,
+} from '../../services/complaint'
+import './index.scss'
+import { PlusOutlined } from "@ant-design/icons"
+import { useUser } from "../User/hooks"
+
+const ComplaintHandle: React.FC = (props: any) => {
+  const columns: any = [
+    {
+      title: 'ID',
+      dataIndex: 'id',
+      search: false
+    },
+    {
+      title: '投诉类型',
+      dataIndex: 'class_name',
+      search: true,
+      valueEnum: {
+        1: { text: '投诉' },
+        2: { text: '建议' }
+      }
+    },
+    {
+      title: '投诉人',
+      dataIndex: 'apply_people',
+      search: true,
+    },
+    {
+      title: '联系电话',
+      dataIndex: 'apply_people_phone',
+      search: true,
+    },
+    {
+      title: '投诉内容',
+      dataIndex: 'apply_content',
+      search: false,
+    },
+    {
+      title: '投诉日期',
+      dataIndex: 'created_at',
+      search: false,
+      valueType: 'dateTime',
+    },
+    {
+      title: '状态',
+      dataIndex: 'status',
+      search: false,
+      valueEnum: {
+        1: { text: '未派单' },
+        2: { text: '已派单' },
+        3: { text: '已完结' },
+      }
+    },
+    {
+      title: '操作',
+      dataIndex: 'option',
+      search: false,
+      render: (_, row, index, action) => {
+        return [
+          <Button
+            className="mr-1.5"
+            onClick={() => {
+              orderForm.setFieldsValue(row)
+              setState(prevState => ({
+                ...prevState,
+                formMode: 'send',
+                orderVisible: true,
+                editId: row.id
+              }))
+            }}
+          >转单</Button>,
+          <Button
+            className="mr-1.5"
+            onClick={() => {
+              setState(prevState => ({
+                ...prevState,
+                formMode: 'return',
+                orderVisible: true
+              }))
+            }}
+          >退单</Button>,
+          <Button
+            className="mr-1.5"
+            onClick={() => {
+              props.history.push('/admin/fix/order-detail')
+            }}
+          >详情</Button>,
+          <Button onClick={() => {
+            setState(prevState => ({
+              ...prevState,
+              formMode: 'finish',
+              orderVisible: true
+            }))
+          }}>办结</Button>
+        ]
+      }
+    }
+  ]
+
+  const [pic, setPic]: any = React.useState([])
+  const [cUsers, setUsers]: any = useUser()
+
+  React.useEffect(() => {
+    setUsers()
+  }, [])
+
+  const uploadButton = (
+    <div>
+      <PlusOutlined />
+      <div style={{ marginTop: 8 }}>上传图片</div>
+    </div>
+  )
+  const [state, setState] = React.useState({
+    visible: false,
+    orderVisible: false,
+    editId: null,
+    formMode: 'send'
+  })
+
+  const FinishForm = <React.Fragment>
+    <Form.Item label='处理意见' name="feedback" rules={[{ required: true }]}>
+      <Input.TextArea placeholder="多行输入" rows={4} />
+    </Form.Item>
+    <Form.Item label='处理后照片' name="repair_pic" rules={[{ required: true }]}>
+      <Upload
+        action="http://localhost:3000/api/v1/upload"
+        listType="picture-card"
+        fileList={pic}
+        onChange={(({ fileList }) => setPic(fileList))}
+      >{ uploadButton }</Upload>
+    </Form.Item>
+  </React.Fragment>
+
+  // 报修退单
+  const ChargeBackForm = <React.Fragment>
+    <Form.Item label='处理意见' name="feedback" rules={[{ required: true }]}>
+      <Input.TextArea placeholder="多行输入" rows={4} />
+    </Form.Item>
+  </React.Fragment>
+
+  const SendForm = <React.Fragment>
+    <Form.Item label='处理人' name="current_uid" rules={[{ required: true }]}>
+      <Select placeholder='请选择' options={cUsers} />
+    </Form.Item>
+    <Form.Item label='处理意见' name="feedback" rules={[{ required: true }]}>
+      <Input.TextArea placeholder="多行输入" rows={4} />
+    </Form.Item>
+  </React.Fragment>
+
+  const Forms = {
+    return: ChargeBackForm,
+    finish: FinishForm,
+    send: SendForm
+  }
+
+  const actionRef: any = React.useRef<ActionType>()
+  const [orderForm] = Form.useForm()
+
+  const onSubmit = () => {
+    const _Api = {
+      send: ComplaintOrderSend,
+      refund: ComplaintOrderRefund,
+      finish: ComplaintOrderFinish
+    }
+    orderForm.validateFields().then(async values => {
+      await _Api[state.formMode]({ ...values, id: state.editId })
+      message.success('操作成功!')
+      orderForm.resetFields()
+      actionRef.current?.reloadAndRest()
+      setState(prevState => ({ ...prevState, orderVisible: false, editId: null }))
+    })
+  }
+
+  return (
+    <React.Fragment>
+      <ProTable
+        headerTitle="投诉建议/投诉受理"
+        actionRef={actionRef}
+        rowKey="key"
+        request={ComplaintApi}
+        params={{ status: 2 }}
+        columns={columns}
+      />
+      <Modal
+        title='转单'
+        visible={state.orderVisible}
+        onOk={onSubmit}
+        onCancel={() => setState(pre => ({ ...pre, orderVisible: false }))}
+      >
+        <Form
+            labelCol={{ span: 5 }}
+            wrapperCol={{ span: 15 }}
+            form={orderForm}
+          >
+          { Forms[state.formMode] }
+          </Form>
+      </Modal>
+    </React.Fragment>
+  )
+}
+
+export default withRouter(ComplaintHandle)

+ 45 - 6
src/views/Complaint/index.tsx

@@ -1,11 +1,12 @@
 import React from 'react'
 import type { ActionType } from '@ant-design/pro-table'
 import ProTable from '@ant-design/pro-table'
-import {Button, Modal, Form, Input, message, Select, Upload} from 'antd'
+import { Button, Modal, Form, Input, message, Select, Upload } from 'antd'
 import { withRouter } from 'react-router-dom'
-import { ComplaintApi } from '../../services/complaint'
+import { ComplaintApi, ComplaintOrderSend } from '../../services/complaint'
 import './index.scss'
-import {PlusOutlined} from "@ant-design/icons";
+import { PlusOutlined } from "@ant-design/icons"
+import { useUser } from "../User/hooks"
 
 const ComplaintPage: React.FC = (props: any) => {
   const columns: any = [
@@ -45,8 +46,13 @@ const ComplaintPage: React.FC = (props: any) => {
     },
     {
       title: '状态',
-      dataIndex: 'phone',
+      dataIndex: 'status',
       search: false,
+      valueEnum: {
+        1: { text: '未派单' },
+        2: { text: '已派单' },
+        3: { text: '已完结' },
+      }
     },
     {
       title: '操作',
@@ -92,6 +98,11 @@ const ComplaintPage: React.FC = (props: any) => {
   ]
 
   const [pic, setPic]: any = React.useState([])
+  const [cUsers, setUsers]: any = useUser()
+
+  React.useEffect(() => {
+    setUsers()
+  }, [])
 
   const uploadButton = (
     <div>
@@ -107,14 +118,12 @@ const ComplaintPage: React.FC = (props: any) => {
 
   const actionRef: any = React.useRef<ActionType>()
   const [form] = Form.useForm()
-  const [orderForm] = Form.useForm()
 
   const onSubmit = () => {
     form.validateFields().then(async values => {
       await ComplaintApi({
         method: 'post',
         ...values,
-        garden_id: 1,
         apply_pic: pic.map(({ response }) => response.data),
       })
       message.success('操作成功!')
@@ -124,6 +133,17 @@ const ComplaintPage: React.FC = (props: any) => {
     })
   }
 
+  const [orderForm] = Form.useForm()
+  const handleSendOrder = () => {
+    orderForm.validateFields().then(async values => {
+      await ComplaintOrderSend({ ...values, id: state.editId })
+      message.success('操作成功!')
+      orderForm.resetFields()
+      actionRef.current?.reloadAndRest()
+      setState(prevState => ({ ...prevState, orderVisible: false, editId: null }))
+    })
+  }
+
   return (
     <React.Fragment>
       <ProTable
@@ -142,6 +162,25 @@ const ComplaintPage: React.FC = (props: any) => {
         ]}
         columns={columns}
       />
+      <Modal
+        title='派单'
+        visible={state.orderVisible}
+        onOk={handleSendOrder}
+        onCancel={() => setState(pre => ({ ...pre, orderVisible: false }))}
+      >
+        <Form
+          labelCol={{ span: 5 }}
+          wrapperCol={{ span: 15 }}
+          form={orderForm}
+        >
+          <Form.Item label='报修师傅' name="current_uid" rules={[{ required: true }]}>
+            <Select placeholder='请选择' options={cUsers} />
+          </Form.Item>
+          <Form.Item label='处理意见' name="feedback" rules={[{ required: true }]}>
+            <Input.TextArea placeholder="多行输入" rows={4} />
+          </Form.Item>
+        </Form>
+      </Modal>
       <Modal
         title='添加投诉/建议'
         visible={state.visible}

+ 139 - 0
src/views/Complaint/return-visit.tsx

@@ -0,0 +1,139 @@
+import React, { useRef } from 'react'
+import type { ActionType } from '@ant-design/pro-table'
+import ProTable from '@ant-design/pro-table'
+import { Button, Modal, Form, Input, message, Select } from 'antd'
+import { withRouter } from 'react-router-dom'
+import { ComplaintOrderFinish, ComplaintApi } from '../../services/complaint'
+import './index.scss'
+
+const ComplaintReturnVisit: React.FC = (props: any) => {
+  const columns: any = [
+    {
+      title: 'ID',
+      dataIndex: 'id',
+      search: false
+    },
+    {
+      title: '投诉类型',
+      dataIndex: 'suggestion_type',
+      search: true,
+      valueEnum: {
+        1: { text: '投诉' },
+        2: { text: '建议' }
+      }
+    },
+    {
+      title: '投诉人',
+      dataIndex: 'user_name',
+      search: true,
+    },
+    {
+      title: '联系电话',
+      dataIndex: 'user_name',
+      search: true,
+    },
+    {
+      title: '投诉内容',
+      dataIndex: 'user_name',
+      search: false,
+    },
+    {
+      title: '投诉日期',
+      dataIndex: 'user_name',
+      search: false,
+    },
+    {
+      title: '状态',
+      dataIndex: 'status',
+      search: false,
+      valueEnum: {
+        1: { text: '未派单' },
+        2: { text: '已派单' },
+        3: { text: '已完结' },
+      }
+    },
+    {
+      title: '操作',
+      dataIndex: 'option',
+      search: false,
+      render: (_, row, index, action) => {
+        return [
+          <Button
+            className="mr-1.5"
+            onClick={() => {
+              orderForm.setFieldsValue(row)
+              setState(prevState => ({
+                ...prevState,
+                formMode: 'send',
+                orderVisible: true,
+                editId: row.id
+              }))
+            }}
+          >回访</Button>,
+          <Button
+            className="mr-1.5"
+            onClick={() => {
+              props.history.push('/admin/fix/order-detail')
+            }}
+          >详情</Button>,
+        ]
+      }
+    }
+  ]
+
+  const [state, setState] = React.useState({
+    orderVisible: false,
+    editId: null,
+    formMode: 'send'
+  })
+
+  const actionRef: any = useRef<ActionType>()
+  const [orderForm] = Form.useForm()
+
+  const onSubmit = () => {
+    orderForm.validateFields().then(async values => {
+      await ComplaintOrderFinish({ ...values, id: state.editId })
+      message.success('操作成功!')
+      orderForm.resetFields()
+      actionRef.current?.reloadAndRest()
+      setState(prevState => ({ ...prevState, orderVisible: false, editId: null }))
+    })
+  }
+
+  return (
+    <React.Fragment>
+      <ProTable
+        headerTitle="投诉建议/投诉回访"
+        actionRef={actionRef}
+        rowKey="key"
+        request={ComplaintApi}
+        params={{ status: 3 }}
+        columns={columns}
+      />
+      <Modal
+        title='投诉回访'
+        visible={state.orderVisible}
+        onOk={onSubmit}
+        onCancel={() => setState(pre => ({ ...pre, orderVisible: false }))}
+      >
+        <Form
+          labelCol={{ span: 5 }}
+          wrapperCol={{ span: 15 }}
+          form={orderForm}
+        >
+          <Form.Item label='满意度' name="return_visit_level" rules={[{ required: true }]}>
+            <Select placeholder="请选择" options={[
+              { label: '满意', value: 1 },
+              { label: '不满意', value: 2 },
+            ]} />
+          </Form.Item>
+          <Form.Item label='业主评价' name="return_visit_content" rules={[{ required: true }]}>
+            <Input.TextArea placeholder="多行输入" rows={4} />
+          </Form.Item>
+        </Form>
+      </Modal>
+    </React.Fragment>
+  )
+}
+
+export default withRouter(ComplaintReturnVisit)