董国庆
2026-03-05 eaff6e1028803aef46ef7e760f1543697789a536
所有的按钮权限
14个文件已修改
726 ■■■■■ 已修改文件
src/views/assetManagement/fleetManagement/detail.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/assetManagement/fleetManagement/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/assetManagement/ruleConfig/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/attendance/address/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/attendance/plan/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/attendance/shift/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/attendance/statistics/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/message/index.vue 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/personnel/personnelManagement/index.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/taskOrder/taskOrderCenter/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/service/review/personnel/index.vue 263 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/service/review/policyApplication/index.vue 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/service/ticket/feedbackType/index.vue 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/service/ticket/workOrder/index.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/assetManagement/fleetManagement/detail.vue
@@ -101,29 +101,29 @@
    ellipsis: true,
    resizable: true,
  },
   {
  {
    title: '车辆颜色',
    align: 'left',
    key: 'vehicleColor',
    ellipsis: true,
    resizable: true,
  },
  // {
  //   title: '采购来源',
  //   align: 'left',
  //   key: 'procurementSource',
  //   ellipsis: true,
  //   resizable: true,
  //   render: (row) => <span>{row.procurementSource || '-'}</span>,
  // },
  // {
  //   title: '运营区域',
  //   align: 'left',
  //   key: 'locationName',
  //   ellipsis: true,
  //   resizable: true,
  //   render: (row) => <span>{row.locationName || '-'}</span>,
  // },
  {
    title: '采购来源',
    align: 'left',
    key: 'procurementSource',
    ellipsis: true,
    resizable: true,
    render: row => <span>{row.procurementSource || '-'}</span>,
  },
  {
    title: '运营区域',
    align: 'left',
    key: 'locationName',
    ellipsis: true,
    resizable: true,
    render: row => <span>{row.locationName || '-'}</span>,
  },
  {
    title: '状态',
    align: 'left',
src/views/assetManagement/fleetManagement/index.vue
@@ -188,6 +188,7 @@
    fleetName: row.fleetName,
    operationsUserName: row.operationsUserName,
    phoneNumber: row.phoneNumber,
    electronicName: row.electronicName
  }
  fleetFormModalVisible.value = true
src/views/assetManagement/ruleConfig/index.vue
@@ -888,7 +888,7 @@
    <!-- Footer Actions (Fixed at Bottom via Flexbox Layout) -->
    <div class=" bg-white px-6 py-4 flex justify-end gap-3 border-t border-gray-100 flex-shrink-0 z-50">
      <n-button>取消</n-button>
      <n-button type="primary" @click="handleSave">保存</n-button>
      <n-button type="primary" @click="handleSave" v-permission="5031">保存</n-button>
    </div>
  </div>
</template>
src/views/operations/attendance/address/index.vue
@@ -84,6 +84,7 @@
        <NSpace>
          <NButton
            text
            v-permission="70212"
            type='primary'
            onClick={() => handleEdit(row)}
          >
@@ -91,6 +92,7 @@
          </NButton>
          <NButton
            text
            v-permission="70214"
            type='primary'
            onClick={() => {
              dialog.create({
@@ -112,7 +114,7 @@
          >
            { row.status === 1 ? '禁用' : '启用' }
          </NButton>
          <NPopconfirm onPositiveClick={() => delteteUser(row.id!)}>
          <NPopconfirm v-permission="70213" onPositiveClick={() => delteteUser(row.id!)}>
            {{
              default: () => '确认删除',
              trigger: () => <NButton text type="error">删除</NButton>,
@@ -220,7 +222,7 @@
      <n-card class="flex-1">
        <template #header>
          <n-flex justify="flex-end">
          <n-flex justify="flex-end" v-permission="70211">
            <NButton type="primary" secondary @click="handleAdd">
              新增打卡地
            </NButton>
src/views/operations/attendance/plan/index.vue
@@ -238,11 +238,11 @@
        <n-date-picker v-model:value="selectedMonth" placeholder="选择月份" type="month" style="width: 260px"
          @update:value="handleMonthChange" />
        <div class="flex gap-2">
          <n-button style="width: 84px;height: 32px;background-color: #E6F4FF;color: #0068FF;border: 1px solid #7ABDFF;"
          <n-button  v-permission="70252" style="width: 84px;height: 32px;background-color: #E6F4FF;color: #0068FF;border: 1px solid #7ABDFF;"
            @click="handleCopy">复制</n-button>
          <n-button style="width: 84px;height: 32px;background-color: #E6F4FF;color: #0068FF;border: 1px solid #7ABDFF;"
          <n-button  v-permission="70253" style="width: 84px;height: 32px;background-color: #E6F4FF;color: #0068FF;border: 1px solid #7ABDFF;"
            @click="handleDownload">下载表</n-button>
          <n-button type="primary" style="width: 84px; height: 32px" @click="handleEdit">编辑</n-button>
          <n-button  v-permission="70251" type="primary" style="width: 84px; height: 32px" @click="handleEdit">编辑</n-button>
        </div>
      </div>
src/views/operations/attendance/shift/index.vue
@@ -118,12 +118,13 @@
       <NSpace>
          <NButton
            text
            v-permission="70242"
            type='primary'
            onClick={() => handleEdit(row)}
          >
            编辑
          </NButton>
          <NPopconfirm onPositiveClick={() => handleDelete(row.id!)}>
          <NPopconfirm  v-permission="70243" onPositiveClick={() => handleDelete(row.id!)}>
            {{
              default: () => '确认删除',
              trigger: () => <NButton text type="error">删除</NButton>,
@@ -180,7 +181,7 @@
      <n-card class="flex-1">
        <template #header>
          <n-flex justify="flex-end">
          <n-flex justify="flex-end"  v-permission="70241">
            <NButton type="primary" secondary @click="handleAdd">
              新增班次
            </NButton>
src/views/operations/attendance/statistics/index.vue
@@ -89,7 +89,7 @@
    width: 134,
    fixed: 'right',
    render: (row) => (
      <NButton text type="primary" onClick={() => handleViewDetail(row)}>
      <NButton v-permission="70222" text type="primary" onClick={() => handleViewDetail(row)}>
        打卡明细
      </NButton>
    )
@@ -157,7 +157,7 @@
    <n-card style="border-radius: 6px; margin-top: 12px" content-style="padding: 12px">
       <template #header>
          <n-flex justify="flex-end">
          <n-flex justify="flex-end" v-permission="70221">
            <NButton type="primary" secondary @click="handleExport">
              导出
            </NButton>
src/views/operations/message/index.vue
@@ -1,128 +1,163 @@
<script setup lang="ts">
import { ref, h } from 'vue'
import { useBoolean } from '@/hooks'
import type { DataTableColumns } from 'naive-ui'
import { NCheckbox } from 'naive-ui'
import { getNoticeList, updateNoticeConfig } from '@/service/api/attendance'
import { ref, h } from "vue";
import { useBoolean } from "@/hooks";
import type { DataTableColumns } from "naive-ui";
import { NCheckbox } from "naive-ui";
import { getNoticeList, updateNoticeConfig } from "@/service/api/attendance";
const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)
const {
  bool: loading,
  setTrue: startLoading,
  setFalse: endLoading,
} = useBoolean(false);
const tableData = ref<any[]>([])
const tableData = ref<any[]>([]);
const columns: DataTableColumns<any> = [
  {
    title: '序号',
    key: 'serialNumber',
    title: "序号",
    key: "serialNumber",
    width: 80,
  },
  {
    title: '通知类型',
    key: 'notificationType',
    title: "通知类型",
    key: "notificationType",
    render: (row) => {
      switch (row.notificationType) {
        //通知类型 1=新增事故,2=事故即将超时提示,3=事故超时提示,4=排班信息变动,5=事故状态变更,6=新增任务,7=任务过期提示,8=版本更新提示,9=变更协议政策内容,10=变更协议内容并需用户授权,11=打卡成功通知
        case 1:
          return '新增事故'
          return "新增事故";
        case 2:
          return '事故即将超时提示'
          return "事故即将超时提示";
        case 3:
          return '事故超时提示'
          return "事故超时提示";
        case 4:
          return '排班信息变动'
          return "排班信息变动";
        case 5:
          return '事故状态变更'
          return "事故状态变更";
        case 6:
          return '新增任务'
          return "新增任务";
        case 7:
          return '任务过期提示'
          return "任务过期提示";
        case 8:
          return '版本更新提示'
          return "版本更新提示";
        case 9:
          return '变更协议政策内容'
          return "变更协议政策内容";
        case 10:
          return '变更协议内容并需用户授权'
          return "变更协议内容并需用户授权";
        case 11:
          return '打卡成功通知'
          return "打卡成功通知";
        default:
          return row.notificationType
          return row.notificationType;
      }
    }
    },
  },
  {
    title: '通知方式',
    key: 'method',
    title: "通知方式",
    key: "method",
    render: (row) => {
      return h('div', { class: 'flex items-center gap-4' }, [
        h(NCheckbox, {
          checked: row.isPush,
          onUpdateChecked: (value: boolean) => {
            row.isPush = value
          }
        }, { default: () => 'PUSH推送' }),
        h(NCheckbox, {
          checked: row.isMessage,
          onUpdateChecked: (value: boolean) => {
            row.isMessage = value
          }
        }, { default: () => '短信通知' })
      ])
    }
      return h("div", { class: "flex items-center gap-4" }, [
        h(
          NCheckbox,
          {
            checked: row.isPush,
            onUpdateChecked: (value: boolean) => {
              row.isPush = value;
            },
          },
          { default: () => "PUSH推送" }
        ),
        h(
          NCheckbox,
          {
            checked: row.isMessage,
            onUpdateChecked: (value: boolean) => {
              row.isMessage = value;
            },
          },
          { default: () => "短信通知" }
        ),
      ]);
    },
  },
  {
    title: '更新时间',
    key: 'updateTime',
  }
]
    title: "更新时间",
    key: "updateTime",
  },
];
const handleSave = () => {
  console.log('保存', tableData.value)
  startLoading()
  updateNoticeConfig({ notifications: tableData.value }).then((res) => {
    if (res.code === 200) {
      window.$message.success('保存成功')
    }
  }).finally(() => {
    getList()
    endLoading()
  })
}
  console.log("保存", tableData.value);
  startLoading();
  updateNoticeConfig({ notifications: tableData.value })
    .then((res) => {
      if (res.code === 200) {
        window.$message.success("保存成功");
      }
    })
    .finally(() => {
      getList();
      endLoading();
    });
};
async function getList() {
  startLoading()
  getNoticeList().then((res) => {
    tableData.value = res.data || []
    tableData.value.forEach((item: any, index: number) => {
     item.serialNumber = (pageParams.value.pageNum - 1) * pageParams.value.pageSize + index + 1
  startLoading();
  getNoticeList()
    .then((res) => {
      tableData.value = res.data || [];
      tableData.value.forEach((item: any, index: number) => {
        item.serialNumber =
          (pageParams.value.pageNum - 1) * pageParams.value.pageSize +
          index +
          1;
      });
    })
  }).finally(() => {
    endLoading()
  })
    .finally(() => {
      endLoading();
    });
}
onMounted(() => {
  getList()
})
  getList();
});
</script>
<template>
  <div class="h-full flex-col">
    <n-card style="border-radius: 6px; overflow: hidden;"
      content-style="padding: 12px; height: 100%; display: flex; flex-direction: column;">
      <div style="flex: 1; overflow: auto;">
        <n-data-table :columns="columns" :data="tableData" :loading="loading" :bordered="false" :header-height="18"
          :row-height="18" />
    <n-card
      style="border-radius: 6px; overflow: hidden"
      content-style="padding: 12px; height: 100%; display: flex; flex-direction: column;"
    >
      <div style="flex: 1; overflow: auto">
        <n-data-table
          :columns="columns"
          :data="tableData"
          :loading="loading"
          :bordered="false"
          :header-height="18"
          :row-height="18"
        />
      </div>
    </n-card>
    <div class="flex justify-end absolute bottom-0 left-0 right-0"
      style="background-color: white; padding: 16px 24px; border-radius: 6px;">
      <n-button type="primary" style="width: 84px; height: 32px" @click="handleSave">保存</n-button>
    <div
      class="flex justify-end absolute bottom-0 left-0 right-0"
      style="background-color: white; padding: 16px 24px; border-radius: 6px"
    >
      <n-button
        v-permission="7041"
        type="primary"
        style="width: 84px; height: 32px"
        @click="handleSave"
        >保存</n-button
      >
    </div>
  </div>
</template>
<style scoped>
:deep(.n-data-table-th) {
  background-color: #F4F6F8;
  background-color: #f4f6f8;
}
</style>
src/views/operations/personnel/personnelManagement/index.vue
@@ -4,6 +4,7 @@
import { useRouter } from 'vue-router'
import type { DataTableColumns } from 'naive-ui'
import { NButton, NTag, NDropdown } from 'naive-ui'
import { usePermission } from '@/hooks'
import { getOperationsUserList, exportOperationsUserTemplate, exportOperationsUser, importOperationsUser,
  addOperationsUser, editOperationsUser, updateOperationsUserStatus, deleteOperationsUser } from '@/service/api/attendance'
import { fetchRoleList } from '@/service/api/fleet'
@@ -15,6 +16,7 @@
const router = useRouter()
const dialog = useDialog()
const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)
const { hasPermission } = usePermission()
const searchModel = ref({
  nickName: '',
@@ -146,6 +148,7 @@
  {
    label: '编辑',
    key: 'edit',
    show: hasPermission(70115),
    props: {
      onClick: () => handleEdit(row)
    }
@@ -153,6 +156,7 @@
  {
    label: row.status ? '禁用' : '启用',
    key: 'toggle',
    show: hasPermission(70116),
    props: {
      onClick: () => {
        updateOperationsUserStatus({
@@ -170,6 +174,7 @@
  {
    label: '重置密码',
    key: 'password',
    show: hasPermission(70117),
    props: {
      onClick: () => {
        handleResetPassword(row)
@@ -179,6 +184,7 @@
  {
    label: '删除',
    key: 'delete',
    show: hasPermission(70118),
    props: {
      onClick: () => {
        dialog.create({
@@ -274,7 +280,7 @@
    fixed: 'right',
    render: (row) => (
      <div class="flex gap-3">
        <a style={{ color: '#0068FF', cursor: 'pointer' }} onClick={() => router.push(`/operations/personnel/personnelManagement/detail/${row.id}`)}>详情</a>
        <a v-permission="70111" style={{ color: '#0068FF', cursor: 'pointer' }} onClick={() => router.push(`/operations/personnel/personnelManagement/detail/${row.id}`)}>详情</a>
        <NDropdown options={moreOptions(row)} trigger="click">
          <a style={{ color: '#0068FF', cursor: 'pointer' }}>更多</a>
        </NDropdown>
@@ -354,10 +360,10 @@
    <n-card class="flex-1 mt-12px">
      <template #header>
        <n-flex justify="flex-end">
          <n-button @click="handleExport" style="width: 84px; height: 32px">导出</n-button>
          <n-button @click="handleImport" style="width: 84px; height: 32px">导入</n-button>
          <n-button @click="handleDownloadTemplate" style="width: 84px; height: 32px">下载模板</n-button>
          <n-button style="width: 84px;height: 32px;background-color: #E6F4FF;color: #0068FF;border: 1px solid #7ABDFF;"
          <n-button v-permission="70112" @click="handleExport" style="width: 84px; height: 32px">导出</n-button>
          <n-button v-permission="70113" @click="handleImport" style="width: 84px; height: 32px">导入</n-button>
          <n-button v-permission="70112" @click="handleDownloadTemplate" style="width: 84px; height: 32px">下载模板</n-button>
          <n-button v-permission="70114" style="width: 84px;height: 32px;background-color: #E6F4FF;color: #0068FF;border: 1px solid #7ABDFF;"
            @click="handleAdd">新增</n-button>
        </n-flex>
      </template>
src/views/operations/taskOrder/taskOrderCenter/index.vue
@@ -342,6 +342,7 @@
        <NSpace>
          {(row.status === 0 || row.status === 1) && <NButton
            text
             v-permission="7053"
            type='primary'
            onClick={() => modalRef.value.openModal(row.id)}
          >
@@ -349,12 +350,13 @@
          </NButton>}
          <NButton
            text
            v-permission="7054"
            type='primary'
            onClick={() => detailModalRef.value.openModal(row.id)}
          >
            详情
          </NButton>
          <NPopconfirm onPositiveClick={() => handleDeltete(row.id!)}>
          <NPopconfirm  v-permission="7055" onPositiveClick={() => handleDeltete(row.id!)}>
            {{
              default: () => '确认删除',
              trigger: () => <NButton text type="error">删除</NButton>,
@@ -388,8 +390,8 @@
    <n-card style="border-radius: 6px; margin-top: 12px" content-style="padding: 12px">
      <template #header>
        <n-flex justify="flex-end">
          <n-button @click="handleExport" style="width: 84px; height: 32px">导出</n-button>
          <NButton type="primary" secondary @click="handleAdd">
          <n-button  v-permission="7051" @click="handleExport" style="width: 84px; height: 32px">导出</n-button>
          <NButton  v-permission="7052" type="primary" secondary @click="handleAdd">
            新增任务
          </NButton>
        </n-flex>
src/views/service/review/personnel/index.vue
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, h, onMounted } from "vue";
<script setup lang="tsx">
import { ref, onMounted } from "vue";
import type { DataTableColumns } from "naive-ui";
import { NButton, NTag, NAvatar, NImage } from "naive-ui";
import { useBoolean } from "@/hooks";
@@ -64,19 +64,19 @@
    align: "center",
    render: (row) => {
      const displayName = row.nickName || "-";
      return h("div", { class: "flex items-center justify-center gap-2" }, [
        h(
          NAvatar,
          {
            round: true,
            size: 32,
            style: { backgroundColor: "#e0e0e0" },
            src: row.avatar || undefined,
          },
          { default: () => displayName.charAt(0) }
        ),
        h("span", displayName),
      ]);
      return (
        <div class="flex items-center justify-center gap-2">
          <NAvatar
            round
            size={32}
            style={{ backgroundColor: "#e0e0e0" }}
            src={row.avatar || undefined}
          >
            {displayName.charAt(0)}
          </NAvatar>
          <span>{displayName}</span>
        </div>
      );
    },
  },
  {
@@ -100,12 +100,10 @@
      const roleName = Array.isArray(row.roleNames)
        ? row.roleNames.join("、")
        : row.roleNames || "-";
      return h(
        NTag,
        { type: "info", size: "small" },
        {
          default: () => roleName,
        }
      return (
        <NTag type="info" size="small">
          {roleName}
        </NTag>
      );
    },
  },
@@ -117,12 +115,10 @@
    render: (row) => {
      const statusText = auditStatusLabelMap[row.auditStatus];
      const tagType = auditStatusTagTypeMap[row.auditStatus];
      return h(
        NTag,
        { type: tagType as any, size: "small" },
        {
          default: () => statusText,
        }
      return (
        <NTag type={tagType as any} size="small">
          {statusText}
        </NTag>
      );
    },
  },
@@ -135,62 +131,56 @@
      if (row.idCardFront && row.idCardBack) {
        const idCardFront = JSON.parse(row.idCardFront).url;
        const idCardBack = JSON.parse(row.idCardBack).url;
        return h("div", { class: "flex gap-1 justify-center" }, [
          h(NImage, {
            width: 60,
            height: 40,
            src: idCardFront,
            objectFit: "cover",
            style: { borderRadius: "4px" },
            previewSrc: idCardFront,
          }),
          h(NImage, {
            width: 60,
            height: 40,
            src: idCardBack,
            objectFit: "cover",
            style: { borderRadius: "4px" },
            previewSrc: idCardBack,
          }),
        ]);
        return (
          <div class="flex gap-1 justify-center">
            <NImage
              width={60}
              height={40}
              src={idCardFront}
              objectFit="cover"
              style={{ borderRadius: "4px" }}
              previewSrc={idCardFront}
            />
            <NImage
              width={60}
              height={40}
              src={idCardBack}
              objectFit="cover"
              style={{ borderRadius: "4px" }}
              previewSrc={idCardBack}
            />
          </div>
        );
      }
      return h(
        "div",
        {
          class: "flex gap-1 justify-center",
        },
        [
          h(
            "div",
            {
              style: {
                width: "60px",
                height: "40px",
                backgroundColor: "#f0f0f0",
                borderRadius: "4px",
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
              },
            },
            "📷"
          ),
          h(
            "div",
            {
              style: {
                width: "60px",
                height: "40px",
                backgroundColor: "#f0f0f0",
                borderRadius: "4px",
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
              },
            },
            "📷"
          ),
        ]
      return (
        <div class="flex gap-1 justify-center">
          <div
            style={{
              width: "60px",
              height: "40px",
              backgroundColor: "#f0f0f0",
              borderRadius: "4px",
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
            }}
          >
            📷
          </div>
          <div
            style={{
              width: "60px",
              height: "40px",
              backgroundColor: "#f0f0f0",
              borderRadius: "4px",
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
            }}
          >
            📷
          </div>
        </div>
      );
    },
  },
@@ -202,19 +192,20 @@
    render: (row) => {
      if (row.driverLicense) {
        const driverLicense = JSON.parse(row.driverLicense).url;
        return h(NImage, {
          width: 60,
          height: 40,
          src: driverLicense,
          objectFit: "cover",
          style: { borderRadius: "4px" },
          previewSrc: driverLicense,
        });
        return (
          <NImage
            width={60}
            height={40}
            src={driverLicense}
            objectFit="cover"
            style={{ borderRadius: "4px" }}
            previewSrc={driverLicense}
          />
        );
      }
      return h(
        "div",
        {
          style: {
      return (
        <div
          style={{
            width: "60px",
            height: "40px",
            backgroundColor: "#f0f0f0",
@@ -223,9 +214,10 @@
            alignItems: "center",
            justifyContent: "center",
            margin: "0 auto",
          },
        },
        "📷"
          }}
        >
          📷
        </div>
      );
    },
  },
@@ -239,19 +231,20 @@
        const certificateOfNoCriminalRecord = JSON.parse(
          row.certificateOfNoCriminalRecord
        ).url;
        return h(NImage, {
          width: 60,
          height: 40,
          src: certificateOfNoCriminalRecord,
          objectFit: "cover",
          style: { borderRadius: "4px" },
          previewSrc: certificateOfNoCriminalRecord,
        });
        return (
          <NImage
            width={60}
            height={40}
            src={certificateOfNoCriminalRecord}
            objectFit="cover"
            style={{ borderRadius: "4px" }}
            previewSrc={certificateOfNoCriminalRecord}
          />
        );
      }
      return h(
        "div",
        {
          style: {
      return (
        <div
          style={{
            width: "60px",
            height: "40px",
            backgroundColor: "#f0f0f0",
@@ -260,9 +253,10 @@
            alignItems: "center",
            justifyContent: "center",
            margin: "0 auto",
          },
        },
        "📷"
          }}
        >
          📷
        </div>
      );
    },
  },
@@ -279,28 +273,28 @@
    align: "center",
    fixed: "right",
    render: (row) => {
      return h("div", { class: "flex items-center justify-center gap-2" }, [
        row.auditStatus === 1
          ? h(
              NButton,
              {
                text: true,
                type: "primary",
                onClick: () => handleApprove(row.id),
              },
              { default: () => "审核" }
            )
          : null,
        h(
          NButton,
          {
            text: true,
            type: "error",
            onClick: () => handleDelete(row.id),
          },
          { default: () => "删除" }
        ),
      ]);
      return (
        <div class="flex items-center justify-center gap-2">
          {row.auditStatus === 1 ? (
            <NButton
              v-permission="80112"
              text
              type="primary"
              onClick={() => handleApprove(row.id)}
            >
              审核
            </NButton>
          ) : null}
          <NButton
            v-permission="80113"
            text
            type="error"
            onClick={() => handleDelete(row.id)}
          >
            删除
          </NButton>
        </div>
      );
    },
  },
];
@@ -492,6 +486,7 @@
    >
      <div class="mb-4 flex justify-end gap-2">
        <n-button
         v-permission="80111"
          style="
            width: 84px;
            height: 32px;
src/views/service/review/policyApplication/index.vue
@@ -1,4 +1,4 @@
<script setup lang="ts">
<script setup lang="tsx">
import { ref, h, onMounted } from "vue";
import type { DataTableColumns } from "naive-ui";
import { NButton, NTag, NTooltip } from "naive-ui";
@@ -173,28 +173,28 @@
    align: "center",
    fixed: "right",
    render: (row) => {
      return h("div", { class: "flex items-center justify-center gap-2" }, [
        row.auditStatus === 1
          ? h(
              NButton,
              {
                text: true,
                type: "primary",
                onClick: () => handleApprove(row.id),
              },
              { default: () => "审核" }
            )
          : null,
        h(
          NButton,
          {
            text: true,
            type: "error",
            onClick: () => handleDelete(row.id),
          },
          { default: () => "删除" }
        ),
      ]);
      return (
        <div class="flex items-center justify-center gap-2">
          {row.auditStatus === 1 ? (
            <NButton
              v-permission="80122"
              text
              type="primary"
              onClick={() => handleApprove(row.id)}
            >
              审核
            </NButton>
          ) : null}
          <NButton
            v-permission="80123"
            text
            type="error"
            onClick={() => handleDelete(row.id)}
          >
            删除
          </NButton>
        </div>
      );
    },
  },
];
@@ -230,8 +230,8 @@
    positiveText: "确定",
    negativeText: "取消",
    onPositiveClick: async () => {
      const { error } = await deletePolicyApplicationById(id);
      if (!error) {
      const res = await deletePolicyApplicationById(id);
      if (res.code === 200) {
        window.$message?.success("删除成功");
        getPolicyApplicationList();
      } else {
@@ -243,12 +243,12 @@
const handleConfirmReview = async (data: any) => {
  const auditStatus = data?.result === "pass" ? 2 : 3;
  const { error } = await batchAuditPolicyApplication({
  const res = await batchAuditPolicyApplication({
    auditStatus,
    ids: selectedIds.value,
    auditRemarks: data?.auditRemarks || "",
  });
  if (!error) {
  if (res.code === 200) {
    window.$message?.success("审核成功");
    selectedIds.value = [];
    getPolicyApplicationList();
@@ -370,6 +370,7 @@
    >
      <div class="mb-4 flex justify-end gap-2">
        <n-button
        v-permission="80121"
          style="
            width: 84px;
            height: 32px;
@@ -388,7 +389,7 @@
          :data="tableData"
          :loading="loading"
          :scroll-x="1500"
          :row-key="(row: PolicyApplicationItem) => row.id"
          :row-key="(row: any) => row.id"
          @update:checked-row-keys="handleCheck"
        />
        <Pagination :count="count" @change="changePage" />
src/views/service/ticket/feedbackType/index.vue
@@ -1,4 +1,4 @@
<script setup lang="ts">
<script setup lang="tsx">
import { ref, h, computed, onMounted } from "vue";
import type { DataTableColumns, FormInst, FormRules } from "naive-ui";
import { NButton } from "naive-ui";
@@ -57,27 +57,28 @@
    key: "actions",
    width: 160,
    align: "center",
    render: (row) =>
      h("div", { class: "flex items-center justify-center gap-2" }, [
        h(
          NButton,
          {
            text: true,
            type: "primary",
            onClick: () => handleEdit(row),
          },
          { default: () => "编辑" }
        ),
        h(
          NButton,
          {
            text: true,
            type: "error",
            onClick: () => handleDelete(row),
          },
          { default: () => "删除" }
        ),
      ]),
    render: (row) => {
      return (
        <div class="flex items-center justify-center gap-2">
          <NButton
            v-permission="80232"
            text
            type="primary"
            onClick={() => handleEdit(row)}
          >
            编辑
          </NButton>
          <NButton
            v-permission="8023"
            text
            type="error"
            onClick={() => handleDelete(row)}
          >
            删除
          </NButton>
        </div>
      );
    },
  },
];
@@ -103,8 +104,8 @@
  await formRef.value?.validate();
  const payload = { feedbackType: formModel.value.feedbackType };
  if (modalMode.value === "add") {
    const { error } = await saveFeedbackType(payload);
    if (!error) {
    const res = await saveFeedbackType(payload);
    if (res.code === 200) {
      window.$message?.success("新增成功");
      modalVisible.value = false;
      getFeedbackTypeList();
@@ -113,11 +114,11 @@
    }
    return;
  }
  const { error } = await updateFeedbackType({
  const res = await updateFeedbackType({
    id: formModel.value.id as number,
    ...payload,
  });
  if (!error) {
  if (res.code === 200) {
    window.$message?.success("编辑成功");
    modalVisible.value = false;
    getFeedbackTypeList();
@@ -133,8 +134,8 @@
    positiveText: "确定",
    negativeText: "取消",
    onPositiveClick: async () => {
      const { error } = await deleteFeedbackType(row.id);
      if (!error) {
      const res = await deleteFeedbackType(row.id);
      if (res.code === 200) {
        window.$message?.success("删除成功");
        getFeedbackTypeList();
      } else {
@@ -174,6 +175,7 @@
    >
      <div class="mb-4 flex justify-end gap-2">
        <n-button
          v-permission="80221"
          style="
            width: 84px;
            height: 32px;
src/views/service/ticket/workOrder/index.vue
@@ -1,4 +1,4 @@
<script setup lang="ts">
<script setup lang="tsx">
import { ref, h, onMounted } from "vue";
import type { DataTableColumns } from "naive-ui";
import { NButton } from "naive-ui";
@@ -168,38 +168,43 @@
    width: 260,
    align: "center",
    render: (row) => {
      const buttons = [
        h(
          NButton,
          { text: true, type: "primary", onClick: () => handleView(row) },
          { default: () => "详情" }
        ),
      ];
      if ([1,2].includes(row.handleStatus)) {
        buttons.push(
          h(
            NButton,
            { text: true, type: "primary", onClick: () => handleStart(row) },
            { default: () => "处理" }
          )
        );
      }
      buttons.push(
        h(
          NButton,
          { text: true, type: "primary", onClick: () => handleEdit(row) },
          { default: () => "编辑" }
        ),
        h(
          NButton,
          { text: true, type: "error", onClick: () => handleDelete(row) },
          { default: () => "删除" }
        )
      );
      return h(
        "div",
        { class: "flex items-center justify-center gap-2" },
        buttons
      return (
        <div class="flex items-center justify-center gap-2">
          <NButton
            v-permission="80212"
            text
            type="primary"
            onClick={() => handleView(row)}
          >
            详情
          </NButton>
          {[1, 2].includes(row.handleStatus || 0) ? (
            <NButton
              v-permission="80213"
              text
              type="primary"
              onClick={() => handleStart(row)}
            >
              处理
            </NButton>
          ) : null}
          <NButton
            v-permission="80215"
            text
            type="primary"
            onClick={() => handleEdit(row)}
          >
            编辑
          </NButton>
          <NButton
            v-permission="80216"
            text
            type="error"
            onClick={() => handleDelete(row)}
          >
            删除
          </NButton>
        </div>
      );
    },
  },
@@ -242,11 +247,6 @@
}
function handleStart(row: WorkOrderItem) {
  handleRow.value = row;
  handleModalVisible.value = true;
}
function handleProcess(row: WorkOrderItem) {
  handleRow.value = row;
  handleModalVisible.value = true;
}
@@ -344,8 +344,8 @@
    positiveText: "确定",
    negativeText: "取消",
    onPositiveClick: async () => {
      const { error } = await deleteWorkOrder(row.id);
      if (!error) {
      const res = await deleteWorkOrder(row.id);
      if (res.code === 200) {
        window.$message?.success("删除成功");
        getWorkOrderList();
      } else {
@@ -491,6 +491,7 @@
    >
      <div class="mb-4 flex justify-end gap-2">
        <n-button
          v-permission="80211"
          style="
            width: 96px;
            height: 32px;