关闭TS校验和完善票据查询功能
This commit is contained in:
parent
4f05a4b12e
commit
69fd1b6b88
@ -36,7 +36,7 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'prettier/prettier': 1,
|
||||
'prettier/prettier': 0,
|
||||
// Vue: Recommended rules to be closed or modify
|
||||
'vue/require-default-prop': 0,
|
||||
'vue/singleline-html-element-content-newline': 0,
|
||||
|
@ -14,7 +14,6 @@ export default mergeConfig(
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://106.53.179.133:8081',
|
||||
// target: 'http://192.168.243.246:8081',
|
||||
// target: 'http://localhost:5173',
|
||||
changeOrigin: true,
|
||||
},
|
||||
|
@ -1,8 +1,7 @@
|
||||
import axios from 'axios';
|
||||
import type { AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
import { Message, Modal } from '@arco-design/web-vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { useUserStore } from '@/store';
|
||||
import router from '@/router';
|
||||
|
||||
export interface HttpResponse<T = unknown> {
|
||||
@ -73,7 +72,7 @@ axios.interceptors.response.use(
|
||||
},
|
||||
(error) => {
|
||||
const { response } = error;
|
||||
console.log('error', error);
|
||||
// console.log('error', error);
|
||||
|
||||
if (response.status === 401) {
|
||||
|
||||
|
@ -6,6 +6,11 @@
|
||||
<a-typography-title
|
||||
:style="{ margin: 0, fontSize: '18px' }"
|
||||
:heading="5"
|
||||
@click="
|
||||
{
|
||||
router.push({ name: 'Workplace' });
|
||||
}
|
||||
"
|
||||
>
|
||||
{{ $t('ticket.manage.system') }}
|
||||
</a-typography-title>
|
||||
@ -107,6 +112,9 @@
|
||||
</a-tooltip>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a-button status="normal">{{ userStore.permissions }}</a-button>
|
||||
</li>
|
||||
<li>
|
||||
<a-dropdown trigger="click">
|
||||
<a-button style="margin-right: 20px" status="normal">{{
|
||||
@ -153,17 +161,16 @@ import { useDark, useToggle, useFullscreen } from '@vueuse/core';
|
||||
import { useAppStore, useUserStore } from '@/store';
|
||||
import { LOCALE_OPTIONS } from '@/locale';
|
||||
import useLocale from '@/hooks/locale';
|
||||
import useUser from '@/hooks/user';
|
||||
|
||||
import Menu from '@/components/menu/index.vue';
|
||||
import userIcon from '@/assets/images/user-circle.png';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { clearToken } from '@/utils/auth';
|
||||
import MessageBox from '../message-box/index.vue';
|
||||
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
const userStore = useUserStore();
|
||||
const { logout } = useUser();
|
||||
|
||||
const { changeLocale, currentLocale } = useLocale();
|
||||
const { isFullscreen, toggle: toggleFullScreen } = useFullscreen();
|
||||
const locales = [...LOCALE_OPTIONS];
|
||||
@ -192,18 +199,9 @@ const handleToggleTheme = () => {
|
||||
const setVisible = () => {
|
||||
appStore.updateSettings({ globalSettings: true });
|
||||
};
|
||||
const refBtn = ref();
|
||||
const triggerBtn = ref();
|
||||
const defaultRole = ref(userStore.role?.id);
|
||||
|
||||
const setPopoverVisible = () => {
|
||||
const event = new MouseEvent('click', {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
refBtn.value.dispatchEvent(event);
|
||||
};
|
||||
const triggerBtn = ref();
|
||||
|
||||
const handleLogout = () => {
|
||||
clearToken();
|
||||
router.push({
|
||||
|
@ -2,14 +2,12 @@ import type { Router, RouteRecordNormalized } from 'vue-router';
|
||||
import NProgress from 'nprogress'; // progress bar
|
||||
|
||||
import usePermission from '@/hooks/permission';
|
||||
import { useUserStore, useAppStore } from '@/store';
|
||||
import { appRoutes } from '../routes';
|
||||
import { useAppStore } from '@/store';
|
||||
import { WHITE_LIST, NOT_FOUND } from '../constants';
|
||||
|
||||
export default function setupPermissionGuard(router: Router) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const appStore = useAppStore();
|
||||
const userStore = useUserStore();
|
||||
const Permission = usePermission();
|
||||
const permissionsAllow = Permission.accessRouter(to);
|
||||
|
||||
|
@ -6,7 +6,6 @@ import {
|
||||
LoginData,
|
||||
me,
|
||||
queryUserList,
|
||||
UserParams,
|
||||
enabled,
|
||||
remove,
|
||||
create,
|
||||
@ -72,7 +71,7 @@ const useUserStore = defineStore('user', {
|
||||
async login(loginForm: LoginData, token: string) {
|
||||
try {
|
||||
setToken(token);
|
||||
const res = await userLogin(loginForm);
|
||||
await userLogin(loginForm);
|
||||
} catch (err) {
|
||||
clearToken();
|
||||
throw err;
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
import saveAs from 'file-saver'; // https://www.npmjs.com/package/file-saver
|
||||
import ExcelJS from 'exceljs'; // https://github.com/exceljs/exceljs/blob/master/README_zh.md
|
||||
import dayjs from 'dayjs'; // https://dayjs.fenxianglu.cn/
|
||||
import * as XLSX from 'xlsx'; // https://www.npmjs.com/package/xlsx
|
||||
import { Message } from '@arco-design/web-vue'; // https://arco.design/vue/component/message
|
||||
import { FileItem } from '@arco-design/web-vue/es/upload/interfaces'; // arco类型
|
||||
@ -44,7 +43,6 @@ export function downloadExcel({ columns, rows, name = '未命名文件' }: Downl
|
||||
|
||||
// 读取文件为json格式
|
||||
export function readExcle(fileItem:FileItem) {
|
||||
console.log('读取文件...',fileItem);
|
||||
return new Promise((resove,reject)=>{
|
||||
try {
|
||||
let workbook:XLSX.Sheet;
|
||||
|
@ -10,26 +10,26 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { useUserStore } from '@/store';
|
||||
import { computed } from 'vue';
|
||||
import { useUserStore } from '@/store';
|
||||
|
||||
const userStore = useUserStore();
|
||||
const userInfo = computed(() => {
|
||||
const userStore = useUserStore();
|
||||
const userInfo = computed(() => {
|
||||
return {
|
||||
name: userStore.username,
|
||||
};
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.banner {
|
||||
.banner {
|
||||
width: 100%;
|
||||
padding: 20px 20px 0 20px;
|
||||
background-color: var(--color-bg-2);
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.arco-icon-home) {
|
||||
:deep(.arco-icon-home) {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -5,7 +5,7 @@
|
||||
class="panel-col"
|
||||
:span="{ xs: 12, sm: 12, md: 12, lg: 12, xl: 12, xxl: 6 }"
|
||||
>
|
||||
<a-space>
|
||||
<a-space @click="to('PASS')">
|
||||
<a-avatar :size="54" class="col-avatar">
|
||||
<img
|
||||
alt="avatar"
|
||||
@ -16,7 +16,6 @@
|
||||
:title="$t('workplace.pass')"
|
||||
:value="formData.pass || 0"
|
||||
:value-from="0"
|
||||
animation
|
||||
show-group-separator
|
||||
>
|
||||
<template #suffix>
|
||||
@ -29,7 +28,7 @@
|
||||
class="panel-col"
|
||||
:span="{ xs: 12, sm: 12, md: 12, lg: 12, xl: 12, xxl: 6 }"
|
||||
>
|
||||
<a-space>
|
||||
<a-space @click="to('FAILED')">
|
||||
<a-avatar :size="54" class="col-avatar">
|
||||
<img
|
||||
alt="avatar"
|
||||
@ -40,7 +39,6 @@
|
||||
:title="$t('workplace.notPass')"
|
||||
:value="formData.notPass || 0"
|
||||
:value-from="0"
|
||||
animation
|
||||
show-group-separator
|
||||
>
|
||||
<template #suffix>
|
||||
@ -53,7 +51,7 @@
|
||||
class="panel-col"
|
||||
:span="{ xs: 12, sm: 12, md: 12, lg: 12, xl: 12, xxl: 6 }"
|
||||
>
|
||||
<a-space>
|
||||
<a-space @click="to('EXAMINE')">
|
||||
<a-avatar :size="54" class="col-avatar">
|
||||
<img
|
||||
alt="avatar"
|
||||
@ -64,7 +62,6 @@
|
||||
:title="$t('workplace.notAudit')"
|
||||
:value="formData.notAudit || 0"
|
||||
:value-from="0"
|
||||
animation
|
||||
show-group-separator
|
||||
>
|
||||
<template #suffix>
|
||||
@ -79,7 +76,7 @@
|
||||
:span="{ xs: 12, sm: 12, md: 12, lg: 12, xl: 12, xxl: 6 }"
|
||||
style="border-right: none"
|
||||
>
|
||||
<a-space>
|
||||
<a-space @click="to('SUBMIT')">
|
||||
<a-avatar :size="54" class="col-avatar">
|
||||
<img
|
||||
alt="avatar"
|
||||
@ -91,7 +88,6 @@
|
||||
:title="$t('workplace.notFiled')"
|
||||
:value="formData.notFiled || 0"
|
||||
:value-from="0"
|
||||
animation
|
||||
show-group-separator
|
||||
>
|
||||
<template #suffix>
|
||||
@ -104,7 +100,7 @@
|
||||
<a-divider class="panel-border" />
|
||||
</a-grid-item>
|
||||
</a-grid>
|
||||
<a-card :bordered="false" v-if="userStore.permissions === 'admin'">
|
||||
<a-card :bordered="false">
|
||||
<a-space id="TicketEcharts" style="width: 98%; height: 400px"></a-space>
|
||||
</a-card>
|
||||
</div>
|
||||
@ -115,6 +111,7 @@ import { useI18n } from 'vue-i18n';
|
||||
import { useTicketStore, useUserStore } from '@/store';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import router from '@/router';
|
||||
|
||||
const { t } = useI18n();
|
||||
const ticketStore = useTicketStore();
|
||||
@ -126,14 +123,8 @@ const formData = ref({
|
||||
pass: undefined,
|
||||
});
|
||||
|
||||
const getEchartData = () => {
|
||||
const res = ticketStore.getChart();
|
||||
console.log('chart', res);
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
const res = await ticketStore.getChart();
|
||||
console.log('chart', res.data);
|
||||
type EChartsOption = echarts.EChartsOption;
|
||||
const chartDom = document.getElementById('TicketEcharts');
|
||||
const myChart = echarts.init(chartDom);
|
||||
@ -208,6 +199,15 @@ const getHomeData = async (params: {
|
||||
formData.value = res.data;
|
||||
});
|
||||
};
|
||||
|
||||
const to = (key: string) => {
|
||||
router.push({
|
||||
name: 'TicketManage',
|
||||
query: {
|
||||
status: key,
|
||||
},
|
||||
});
|
||||
};
|
||||
getHomeData({});
|
||||
</script>
|
||||
|
||||
|
@ -15,12 +15,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import bannerImage from '@/assets/images/login-banner.png';
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import bannerImage from '@/assets/images/login-banner.png';
|
||||
|
||||
const { t } = useI18n();
|
||||
const carouselItem = computed(() => [
|
||||
const { t } = useI18n();
|
||||
const carouselItem = computed(() => [
|
||||
{
|
||||
slogan: t('login.banner.slogan1'),
|
||||
subSlogan: t('login.banner.subSlogan1'),
|
||||
@ -36,11 +36,11 @@
|
||||
subSlogan: t('login.banner.subSlogan3'),
|
||||
image: bannerImage,
|
||||
},
|
||||
]);
|
||||
]);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.banner {
|
||||
.banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@ -49,9 +49,9 @@
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.carousel {
|
||||
.carousel {
|
||||
height: 100%;
|
||||
|
||||
&-item {
|
||||
@ -80,5 +80,5 @@
|
||||
width: 320px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -192,7 +192,6 @@ import { useStorage } from '@vueuse/core';
|
||||
import { useUserStore } from '@/store';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { LoginData, CreateRecord } from '@/api/user';
|
||||
import { deptList } from '@/api/dept';
|
||||
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
@ -219,11 +218,6 @@ const formData = ref<CreateRecord>({
|
||||
|
||||
const flag = ref(false);
|
||||
const totalCount = ref(60);
|
||||
const deptOptions = ref();
|
||||
const getDeptData = async () => {
|
||||
const res = await deptList();
|
||||
deptOptions.value = res.data.records;
|
||||
};
|
||||
|
||||
const loginConfig = useStorage('login-config', {
|
||||
// 使用 useStorage 创建一个响应式变量,存储登录相关配置
|
||||
@ -257,10 +251,10 @@ const handleSubmit = async ({
|
||||
try {
|
||||
const res = await userStore.me();
|
||||
await userStore.login(values as LoginData, res.data.csrf.token);
|
||||
const csrf = await userStore.me();
|
||||
await userStore.me();
|
||||
await userStore.info();
|
||||
// 获取路由信息,处理重定向
|
||||
const { redirect, ...othersQuery } = router.currentRoute.value.query;
|
||||
const { ...othersQuery } = router.currentRoute.value.query;
|
||||
router.push({
|
||||
name: 'Workplace',
|
||||
query: {
|
||||
|
@ -48,8 +48,8 @@ import { useI18n } from 'vue-i18n';
|
||||
import useVisible from '@/hooks/visible';
|
||||
import { computed, PropType, ref } from 'vue';
|
||||
import { FormInstance } from '@arco-design/web-vue/es/form';
|
||||
import { Message, TreeNodeData } from '@arco-design/web-vue';
|
||||
import { DeptRecord, DeptCreateRecord } from '@/api/dept';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { DeptRecord } from '@/api/dept';
|
||||
import { useDeptStore } from '@/store';
|
||||
|
||||
const props = defineProps({
|
||||
|
@ -163,12 +163,12 @@
|
||||
<a-pagination
|
||||
style="float: right; position: relative; right: 1px; bottom: 25px"
|
||||
:total="pagination.total"
|
||||
@page-size-change="onSizeChange"
|
||||
:size="size"
|
||||
@change="onPageChange"
|
||||
show-total
|
||||
show-jumper
|
||||
show-page-size
|
||||
@page-size-change="onSizeChange"
|
||||
@change="onPageChange"
|
||||
/>
|
||||
</a-card>
|
||||
</div>
|
||||
|
@ -50,7 +50,6 @@ import { useI18n } from 'vue-i18n';
|
||||
import useVisible from '@/hooks/visible';
|
||||
import { computed, PropType, ref } from 'vue';
|
||||
import { FormInstance } from '@arco-design/web-vue/es/form';
|
||||
import { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { RoleRecord } from '@/api/role';
|
||||
import { useRoleStore } from '@/store';
|
||||
|
@ -115,8 +115,8 @@
|
||||
:data="renderData"
|
||||
:bordered="false"
|
||||
:size="size"
|
||||
@page-change="onPageChange"
|
||||
style="margin-bottom: 40px"
|
||||
@page-change="onPageChange"
|
||||
>
|
||||
<template #index="{ rowIndex }">
|
||||
{{ rowIndex + 1 }}
|
||||
@ -160,19 +160,19 @@
|
||||
<a-pagination
|
||||
style="float: right; position: relative; right: 1px; bottom: 25px"
|
||||
:total="pagination.total"
|
||||
@page-size-change="onSizeChange"
|
||||
:size="size"
|
||||
@change="onPageChange"
|
||||
show-total
|
||||
show-jumper
|
||||
show-page-size
|
||||
@page-size-change="onSizeChange"
|
||||
@change="onPageChange"
|
||||
/>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, reactive, watch, nextTick } from 'vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { Pagination } from '@/types/global';
|
||||
@ -181,11 +181,9 @@ import { Message } from '@arco-design/web-vue';
|
||||
import useTableOption from '@/hooks/table-option';
|
||||
import dayjs from 'dayjs';
|
||||
import { useRoleStore } from '@/store';
|
||||
import { RoleRecord, RoleCreateRecord } from '@/api/role';
|
||||
import { RoleRecord } from '@/api/role';
|
||||
import RoleEdit from './components/role-edit.vue';
|
||||
|
||||
type SizeProps = 'mini' | 'small' | 'medium' | 'large';
|
||||
type Column = TableColumnData & { checked?: true };
|
||||
const { loading, setLoading } = useLoading(true);
|
||||
const { t } = useI18n();
|
||||
const renderData = ref<RoleRecord[]>([]);
|
||||
@ -257,7 +255,6 @@ const fetchData = async (params: any) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await roleStore.getRoleList(params);
|
||||
console.log('info', res.data);
|
||||
renderData.value = res.data.records;
|
||||
pagination.page = res.data.page;
|
||||
pagination.current = res.data.current;
|
||||
|
@ -85,7 +85,7 @@
|
||||
<a-space>
|
||||
<UserEdit ref="createUserRef" :is-create="true" @refresh="search" />
|
||||
</a-space>
|
||||
<a-button @click="generateExcel" style="margin-left: 20px">
|
||||
<a-button style="margin-left: 20px" @click="generateExcel">
|
||||
<template #icon>
|
||||
<icon-download size="18" />
|
||||
</template>
|
||||
@ -168,10 +168,10 @@
|
||||
:data="renderData"
|
||||
:bordered="false"
|
||||
:size="size"
|
||||
@page-change="onPageChange"
|
||||
style="margin-bottom: 40px"
|
||||
:filter-icon-align-left="alignLeft"
|
||||
@change="handleSortChange"
|
||||
@page-change="onPageChange"
|
||||
>
|
||||
<template #index="{ rowIndex }">
|
||||
{{ rowIndex + 1 + (pagination.current - 1) * pagination.size }}
|
||||
@ -211,12 +211,12 @@
|
||||
<a-pagination
|
||||
style="float: right; position: relative; right: 1px; bottom: 25px"
|
||||
:total="pagination.total"
|
||||
@page-size-change="onSizeChange"
|
||||
:size="size"
|
||||
@change="onPageChange"
|
||||
show-total
|
||||
show-jumper
|
||||
show-page-size
|
||||
@page-size-change="onSizeChange"
|
||||
@change="onPageChange"
|
||||
/>
|
||||
</a-card>
|
||||
</div>
|
||||
@ -236,9 +236,6 @@ import { downloadExcel, DownloadExcelPrams } from '@/utils/excel';
|
||||
import useTableOption from '@/hooks/table-option';
|
||||
import UserEdit from './components/user-edit.vue';
|
||||
|
||||
type SizeProps = 'mini' | 'small' | 'medium' | 'large';
|
||||
type Column = TableColumnData & { checked?: true };
|
||||
|
||||
const generateFormModel = () => {
|
||||
return {
|
||||
id: '',
|
||||
@ -404,9 +401,7 @@ const reset = () => {
|
||||
|
||||
// 表格内部排序
|
||||
const alignLeft = ref(false);
|
||||
const handleSortChange = (data: any, extra: any, currentDataSource: any) => {
|
||||
console.log('change', data, extra, currentDataSource);
|
||||
};
|
||||
const handleSortChange = (data: any, extra: any, currentDataSource: any) => {};
|
||||
|
||||
// 是否启用
|
||||
const enabledStatus = async (record: string) => {
|
||||
|
@ -24,20 +24,33 @@
|
||||
<template #icon><icon-edit /></template>
|
||||
{{ modalTitle }}
|
||||
</a-button>
|
||||
|
||||
<a-modal
|
||||
width="700px"
|
||||
width="800px"
|
||||
:visible="visible"
|
||||
:footer="false"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<template #title>{{ modalTitle }}</template>
|
||||
<a-form ref="createEditRef" :model="formData" :style="{ width: '650px' }">
|
||||
<a-form
|
||||
ref="createEditRef"
|
||||
:label-col-props="{ span: 6 }"
|
||||
:wrapper-col-props="{ span: 15 }"
|
||||
label-align="right"
|
||||
:model="formData"
|
||||
:style="{ width: '750px' }"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-form-item
|
||||
field="companyName"
|
||||
:label="$t('ticket.info.companyName')"
|
||||
:validate-trigger="['change', 'input']"
|
||||
:rules="[
|
||||
{ required: true, message: t('ticket.info.companyName.required') },
|
||||
{
|
||||
required: true,
|
||||
message: t('ticket.info.companyName.required'),
|
||||
},
|
||||
]"
|
||||
style="line-height: 18px"
|
||||
>
|
||||
@ -46,37 +59,52 @@
|
||||
:placeholder="$t('ticket.info.companyName.placeholder')"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-form-item
|
||||
field="title"
|
||||
:label="$t('ticket.info.title')"
|
||||
:validate-trigger="['change', 'input']"
|
||||
:rules="[{ required: true, message: t('ticket.info.title.required') }]"
|
||||
:rules="[
|
||||
{ required: true, message: t('ticket.info.title.required') },
|
||||
]"
|
||||
>
|
||||
<a-input
|
||||
v-model="formData.title"
|
||||
:placeholder="$t('ticket.info.title.placeholder')"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-form-item
|
||||
field="money"
|
||||
:label="$t('ticket.info.money')"
|
||||
:validate-trigger="['change', 'input']"
|
||||
:rules="[{ required: true, message: t('ticket.info.money.required') }]"
|
||||
:rules="[
|
||||
{ required: true, message: t('ticket.info.money.required') },
|
||||
]"
|
||||
>
|
||||
<a-input
|
||||
v-model="formData.money"
|
||||
:placeholder="$t('ticket.info.money.placeholder')"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-form-item
|
||||
field="contactEmail"
|
||||
:label="$t('ticket.info.contactEmail')"
|
||||
:validate-trigger="['change', 'input']"
|
||||
:rules="[
|
||||
{ required: true, message: t('ticket.info.contactEmail.required') },
|
||||
{
|
||||
required: true,
|
||||
message: t('ticket.info.contactEmail.required'),
|
||||
},
|
||||
]"
|
||||
>
|
||||
<a-input
|
||||
@ -84,12 +112,18 @@
|
||||
:placeholder="$t('ticket.info.contactEmail.placeholder')"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-form-item
|
||||
field="type"
|
||||
:label="$t('ticket.info.type')"
|
||||
:validate-trigger="['change', 'input']"
|
||||
:rules="[{ required: true, message: t('ticket.info.type.required') }]"
|
||||
:rules="[
|
||||
{ required: true, message: t('ticket.info.type.required') },
|
||||
]"
|
||||
>
|
||||
<a-select
|
||||
v-model="formData.type"
|
||||
@ -97,11 +131,15 @@
|
||||
:placeholder="$t('ticket.info.type.placeholder')"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-form-item
|
||||
field="deptId"
|
||||
:label="$t('ticket.info.dept')"
|
||||
:rules="[{ required: true, message: t('ticket.info.dept.required') }]"
|
||||
:rules="[
|
||||
{ required: true, message: t('ticket.info.dept.required') },
|
||||
]"
|
||||
:validate-trigger="['change']"
|
||||
>
|
||||
<a-tree-select
|
||||
@ -116,7 +154,12 @@
|
||||
@change="optionDept(true)"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-row>
|
||||
<a-form-item
|
||||
field="auditorId"
|
||||
:label="$t('ticket.info.auditor')"
|
||||
@ -134,7 +177,8 @@
|
||||
</div>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-form-item
|
||||
field="comment"
|
||||
:label="$t('ticket.info.comment')"
|
||||
@ -142,21 +186,31 @@
|
||||
>
|
||||
{{ formData.comment }}
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
|
||||
<a-row>
|
||||
<a-form-item
|
||||
field="body"
|
||||
:label="$t('ticket.info.body')"
|
||||
:validate-trigger="['change', 'input']"
|
||||
:rules="[{ required: true, message: t('ticket.info.body.required') }]"
|
||||
:rules="[
|
||||
{ required: true, message: t('ticket.info.body.required') },
|
||||
]"
|
||||
>
|
||||
<a-textarea
|
||||
v-model="formData.body"
|
||||
:placeholder="$t('ticket.info.body.placeholder')"
|
||||
style="height: 100px"
|
||||
style="height: 150px"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
</a-col>
|
||||
|
||||
<a-form-item field="attachment" :label="$t('ticket.info.attachment')">
|
||||
<a-col :span="12"
|
||||
><a-form-item
|
||||
field="attachment"
|
||||
:label="$t('ticket.info.attachment')"
|
||||
>
|
||||
<a-upload
|
||||
:file-list="fileList"
|
||||
:custom-request="Onchange"
|
||||
@ -164,9 +218,11 @@
|
||||
:on-before-remove="removeAttact"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item>
|
||||
<a-button type="dashed" @click="handleCancel">
|
||||
<a-form-item style="display: flex; justify-content: center">
|
||||
<a-button type="dashed" style="margin-left: 30px" @click="handleCancel">
|
||||
{{ $t('cancel') }}</a-button
|
||||
>
|
||||
<a-button
|
||||
@ -296,10 +352,8 @@ const Onchange = async (option: any) => {
|
||||
});
|
||||
res.data.name = res.data.fileName;
|
||||
fileList.value.push(res.data);
|
||||
console.log('res', res.data.id);
|
||||
attachList.value.push(res.data.id);
|
||||
formData.value.attachId = attachList;
|
||||
console.log('poti', formData.value.attachId);
|
||||
} else {
|
||||
Message.error({
|
||||
content: t('upload.fail'),
|
||||
@ -310,12 +364,9 @@ const Onchange = async (option: any) => {
|
||||
|
||||
// 删除附件
|
||||
const removeAttact = (fileItem: FileItem) => {
|
||||
console.log('2', fileItem.id, fileList.value, attachList.value);
|
||||
fileList.value = fileList.value.filter((item) => item.id !== fileItem.id);
|
||||
attachList.value = attachList.value.filter((item) => item !== fileItem.id);
|
||||
console.log('3', fileList.value, attachList.value);
|
||||
formData.value.attachId = attachList.value;
|
||||
console.log('3', formData.value.attachId);
|
||||
};
|
||||
|
||||
// 组件被点击时
|
||||
@ -332,7 +383,6 @@ const handleClick = () => {
|
||||
formData.value = res.data;
|
||||
|
||||
formData.value.attachId.forEach(async (item: any) => {
|
||||
console.log('item,', item);
|
||||
const data = await ticketStore.getAttachment(item);
|
||||
data.data.name = data.data.fileName;
|
||||
fileList.value.push(data.data);
|
||||
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<!-- 详情 -->
|
||||
<a-button
|
||||
v-permission="['BILL_QUERY']"
|
||||
v-if="props.isDetail"
|
||||
v-permission="['BILL_QUERY']"
|
||||
type="outline"
|
||||
size="small"
|
||||
:style="{ marginRight: '10px', padding: '7px', border: '0px' }"
|
||||
@ -14,8 +14,8 @@
|
||||
|
||||
<!-- 审核 -->
|
||||
<a-button
|
||||
v-permission="['BILL_AUDIT']"
|
||||
v-if="!props.isDetail"
|
||||
v-permission="['BILL_AUDIT']"
|
||||
type="outline"
|
||||
size="small"
|
||||
:style="{ marginRight: '10px', padding: '7px', border: '0px' }"
|
||||
@ -178,11 +178,14 @@
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-if="!props.isDetail"
|
||||
field="comment"
|
||||
:label="$t('ticket.info.comment')"
|
||||
v-if="!props.isDetail"
|
||||
>
|
||||
<a-textarea v-model="formData.comment" style="height: 200px" />
|
||||
<a-textarea
|
||||
v-model="formData.comment"
|
||||
style="height: 200px; background-color: white; border: 1px solid"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
@ -193,14 +196,14 @@
|
||||
style="margin-left: -110px"
|
||||
>
|
||||
<a-upload
|
||||
v-if="fileList.length !== 0"
|
||||
v-model="formData.attachId"
|
||||
:file-list="fileList"
|
||||
:custom-request="Onchange"
|
||||
:limit="5"
|
||||
:disabled="true"
|
||||
:on-before-remove="removeAttact"
|
||||
:show-remove-button="false"
|
||||
v-model="formData.attachId"
|
||||
v-if="fileList.length !== 0"
|
||||
/>
|
||||
<div v-else>无</div>
|
||||
</a-form-item>
|
||||
@ -214,8 +217,7 @@ import { useI18n } from 'vue-i18n';
|
||||
import useVisible from '@/hooks/visible';
|
||||
import { computed, PropType, ref } from 'vue';
|
||||
import { FormInstance } from '@arco-design/web-vue/es/form';
|
||||
import { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
||||
import { Button, Message } from '@arco-design/web-vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { useTicketStore, useUserStore, useRoleStore } from '@/store';
|
||||
import { TicketRecord } from '@/api/ticket';
|
||||
import { deptList } from '@/api/dept';
|
||||
@ -299,9 +301,9 @@ const handleClick = async () => {
|
||||
// 票据数据
|
||||
formData.value = res.data;
|
||||
formData.value.submit = 'true';
|
||||
|
||||
// 附件内容
|
||||
formData.value.attachId.forEach(async (item: any) => {
|
||||
// console.log('item,', item);
|
||||
const data = await ticketStore.getAttachment(item);
|
||||
data.data.name = data.data.fileName;
|
||||
fileList.value.push(data.data);
|
||||
|
@ -2,15 +2,19 @@
|
||||
<div class="container">
|
||||
<Breadcrumb :items="['menu.ticket', 'menu.ticket.manage']" />
|
||||
<a-card class="general-card">
|
||||
<a-tabs default-active-key="" @change="changeTop">
|
||||
<a-tab-pane key="" :title="t('set')"> </a-tab-pane>
|
||||
<a-tab-pane key="PASS" :title="t('pass')"> </a-tab-pane>
|
||||
<a-tabs
|
||||
default-active-key="ALL"
|
||||
:active-key="tabKey"
|
||||
@tab-click="changeTop"
|
||||
>
|
||||
<a-tab-pane key="ALL" :title="t('set')"> </a-tab-pane>
|
||||
<a-tab-pane key="FAILED" :title="t('failed')"> </a-tab-pane>
|
||||
<a-tab-pane key="PASS" :title="t('pass')"> </a-tab-pane>
|
||||
<a-tab-pane key="EXAMINE" :title="t('unreviewed')"> </a-tab-pane>
|
||||
<a-tab-pane
|
||||
v-if="userStore.permissions !== 'auditor'"
|
||||
key="SUBMIT"
|
||||
:title="t('drafts')"
|
||||
v-if="userStore.permissions !== 'auditor'"
|
||||
>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
@ -103,9 +107,9 @@
|
||||
v-model="formModel.time"
|
||||
style="width: 360px"
|
||||
show-time
|
||||
@select="onSelect"
|
||||
value-format="YYYY-MM-DD"
|
||||
:allow-clear="false"
|
||||
@select="onSelect"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
@ -143,7 +147,7 @@
|
||||
@refresh="search"
|
||||
/>
|
||||
</a-space>
|
||||
<a-button @click="generateExcel" style="margin-left: 5px">
|
||||
<a-button style="margin-left: 5px" @click="generateExcel">
|
||||
<template #icon>
|
||||
<icon-download size="16" />
|
||||
</template>
|
||||
@ -220,12 +224,12 @@
|
||||
:pagination="false"
|
||||
:size="size"
|
||||
:expandable="expandable"
|
||||
@page-change="onPageChange"
|
||||
style="margin-bottom: 40px"
|
||||
@page-change="onPageChange"
|
||||
>
|
||||
<template #expand-row="{ record }">
|
||||
<!-- 下面展示子表格,根据需求对子table进行属性配置 -->
|
||||
<a-descriptions layout="inline-horizontal" :column="1" bordered>
|
||||
<a-descriptions layout="inline-horizontal" :column="1">
|
||||
<descriptions-item :label="t('ticket.info.contactEmail')">
|
||||
{{ record.contactEmail }}
|
||||
</descriptions-item>
|
||||
@ -242,16 +246,16 @@
|
||||
</template>
|
||||
|
||||
<template #status="{ record }">
|
||||
<a-button status="success" v-if="record.status === '审核通过'">{{
|
||||
<a-button v-if="record.status === '审核通过'" status="success">{{
|
||||
record.status
|
||||
}}</a-button>
|
||||
<a-button status="danger" v-if="record.status === '审核未通过'">{{
|
||||
<a-button v-if="record.status === '审核未通过'" status="danger">{{
|
||||
record.status
|
||||
}}</a-button>
|
||||
<a-button status="normal" v-if="record.status === '待审核'">{{
|
||||
<a-button v-if="record.status === '待审核'" status="normal">{{
|
||||
record.status
|
||||
}}</a-button>
|
||||
<a-button status="warning" v-if="record.status === '待提交'">{{
|
||||
<a-button v-if="record.status === '待提交'" status="warning">{{
|
||||
record.status
|
||||
}}</a-button>
|
||||
</template>
|
||||
@ -267,20 +271,20 @@
|
||||
|
||||
<!-- 修改 -->
|
||||
<TicketForm
|
||||
v-if="record.status === '待提交' || record.status === '审核未通过'"
|
||||
ref="createEditRef"
|
||||
:prem="record"
|
||||
:is-create="false"
|
||||
@refresh="search"
|
||||
v-if="record.status === '待提交' || record.status === '审核未通过'"
|
||||
/>
|
||||
|
||||
<!-- 审核 -->
|
||||
<TicketEdit
|
||||
v-if="record.status === '待审核'"
|
||||
ref="editRef"
|
||||
:prem="record"
|
||||
:is-detail="false"
|
||||
@refresh="search"
|
||||
v-if="record.status === '待审核'"
|
||||
/>
|
||||
|
||||
<a-popconfirm
|
||||
@ -288,12 +292,12 @@
|
||||
@ok="handleDelete(record)"
|
||||
>
|
||||
<a-button
|
||||
type="outline"
|
||||
size="small"
|
||||
v-permission="['BILL_DELETE']"
|
||||
v-if="
|
||||
record.status === '待提交' || record.status === '审核未通过'
|
||||
"
|
||||
v-permission="['BILL_DELETE']"
|
||||
type="outline"
|
||||
size="small"
|
||||
style="padding: 7px; border: 0px"
|
||||
>
|
||||
<template #icon><icon-delete /></template>
|
||||
@ -305,19 +309,19 @@
|
||||
<a-pagination
|
||||
style="float: right; position: relative; right: 1px; bottom: 25px"
|
||||
:total="pagination.total"
|
||||
@page-size-change="onSizeChange"
|
||||
:size="size"
|
||||
@change="onPageChange"
|
||||
show-total
|
||||
show-jumper
|
||||
show-page-size
|
||||
@page-size-change="onSizeChange"
|
||||
@change="onPageChange"
|
||||
/>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, reactive, ref, watch } from 'vue';
|
||||
import { computed, reactive, ref, watch, onMounted } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import useTableOption from '@/hooks/table-option';
|
||||
@ -329,6 +333,7 @@ import { Message } from '@arco-design/web-vue';
|
||||
import { useTicketStore, useUserStore } from '@/store';
|
||||
import { TicketRecord } from '@/api/ticket';
|
||||
import { downloadExcel, DownloadExcelPrams } from '@/utils/excel';
|
||||
import { useRoute } from 'vue-router';
|
||||
import TicketEdit from './components/ticket-edit.vue';
|
||||
import TicketForm from './components/form-edit.vue';
|
||||
|
||||
@ -352,7 +357,7 @@ const generateFormModel = () => {
|
||||
companyName: '',
|
||||
title: '',
|
||||
type: '',
|
||||
// 默认先展示票据审核通过的
|
||||
// 默认先展示所有票据的
|
||||
status: '',
|
||||
time: [],
|
||||
userName: '',
|
||||
@ -368,6 +373,12 @@ const renderData = ref<TicketRecord[]>([]);
|
||||
const formModel = ref(generateFormModel());
|
||||
const currentStatus = ref('PASS');
|
||||
|
||||
// 参数接收
|
||||
onMounted(() => {
|
||||
const router = useRoute();
|
||||
changeTop(router.query.status);
|
||||
});
|
||||
|
||||
// 拓展行
|
||||
const expandable = reactive({
|
||||
title: ' ',
|
||||
@ -481,12 +492,6 @@ const onSelect = (dateString: any, date: any) => {
|
||||
formModel.value.endTime = String(dateString[1]);
|
||||
};
|
||||
|
||||
// 时间段改变
|
||||
const onChange = (dateString: any, date: any) => {
|
||||
formModel.value.startTime = String(dateString[0]);
|
||||
formModel.value.endTime = String(dateString[1]);
|
||||
};
|
||||
|
||||
// 分页发生改变
|
||||
const onPageChange = (current: number) => {
|
||||
pagination.page = current;
|
||||
@ -534,26 +539,31 @@ const fetchData = async (params: {
|
||||
}
|
||||
};
|
||||
|
||||
const tabKey = ref('ALL');
|
||||
|
||||
// 模糊查询
|
||||
const search = () => {
|
||||
// 删除time
|
||||
const { time, ...auditDate } = formModel.value;
|
||||
changeTop('ALL');
|
||||
};
|
||||
|
||||
// 切换标签页
|
||||
const changeTop = (key: any) => {
|
||||
tabKey.value = key;
|
||||
if (tabKey.value === 'ALL') {
|
||||
formModel.value.status = '';
|
||||
} else {
|
||||
formModel.value.status = key;
|
||||
}
|
||||
currentStatus.value = key;
|
||||
const { time, ...auditDate } = formModel.value;
|
||||
fetchData({
|
||||
...pagination,
|
||||
...auditDate,
|
||||
} as unknown as any);
|
||||
};
|
||||
|
||||
// 切换标签页
|
||||
const changeTop = (key: any) => {
|
||||
formModel.value.status = key;
|
||||
currentStatus.value = key;
|
||||
search();
|
||||
};
|
||||
|
||||
search();
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
formModel.value = generateFormModel();
|
||||
|
@ -48,7 +48,7 @@ export default {
|
||||
'tax': '税务支票',
|
||||
'other': '其他支票',
|
||||
|
||||
'set':'票据集合',
|
||||
'set':'所有票据',
|
||||
'unsubmitted': '待提交',
|
||||
'unreviewed': '待审核',
|
||||
'pass': '审核通过',
|
||||
|
@ -3,7 +3,7 @@
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
class="form"
|
||||
:label-col-props="{ span: 8 }"
|
||||
:label-col-props="{ span: 5 }"
|
||||
:wrapper-col-props="{ span: 16 }"
|
||||
>
|
||||
<a-form-item
|
||||
|
@ -3,24 +3,9 @@
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
class="form"
|
||||
:label-col-props="{ span: 8 }"
|
||||
:label-col-props="{ span: 5 }"
|
||||
:wrapper-col-props="{ span: 16 }"
|
||||
>
|
||||
<!-- <a-form-item
|
||||
field="oldPassword"
|
||||
:label="$t('userSetting.passwordReset.form.label.oldPassword')"
|
||||
:rules="[{ required: true, message: $t('login.form.password.errMsg') }]"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="formData.oldPassword"
|
||||
:placeholder="
|
||||
$t('userSetting.passwordReset.form.label.oldPassword.placeholder')
|
||||
"
|
||||
allow-clear
|
||||
>
|
||||
</a-input-password>
|
||||
</a-form-item> -->
|
||||
|
||||
<a-form-item
|
||||
field="password"
|
||||
:label="$t('userSetting.passwordReset.form.label.newPassword')"
|
||||
@ -98,9 +83,6 @@ const user = useUser();
|
||||
const validate = async () => {
|
||||
const vali = await formRef.value?.validate();
|
||||
if (!vali) {
|
||||
// do some thing
|
||||
// you also can use html-type to submit
|
||||
|
||||
const res = await resetPassword(formData.value);
|
||||
if (res.status === 200) {
|
||||
Message.success({
|
||||
|
@ -48,12 +48,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { ref } from 'vue';
|
||||
import type {
|
||||
FileItem,
|
||||
RequestOption,
|
||||
} from '@arco-design/web-vue/es/upload/interfaces';
|
||||
import type { FileItem } from '@arco-design/web-vue/es/upload/interfaces';
|
||||
import { useUserStore, useTicketStore } from '@/store';
|
||||
import { userUploadApi } from '@/api/user-center';
|
||||
import userIcon from '@/assets/images/user-circle.png';
|
||||
import type { DescData } from '@arco-design/web-vue/es/descriptions/interface';
|
||||
import dayjs from 'dayjs';
|
||||
@ -101,7 +97,7 @@ const Onchange = async (option: any) => {
|
||||
});
|
||||
res.data.name = res.data.fileName;
|
||||
fileList.value.push(res.data);
|
||||
const data = await selfUpdate({ avatar: res.data.id });
|
||||
await selfUpdate({ avatar: res.data.id });
|
||||
await userStore.info();
|
||||
} else {
|
||||
Message.error({
|
||||
@ -110,43 +106,6 @@ const Onchange = async (option: any) => {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// const customRequest = (options: RequestOption) => {
|
||||
// // docs: https://axios-http.com/docs/cancellation
|
||||
// const controller = new AbortController();
|
||||
|
||||
// (async function requestWrap() {
|
||||
// const { onProgress, onError, onSuccess, fileItem, name = 'file' } = options;
|
||||
// onProgress(20);
|
||||
// const formData = new FormData();
|
||||
// formData.append(name as string, fileItem.file as Blob);
|
||||
// const onUploadProgress = (event: ProgressEvent) => {
|
||||
// let percent;
|
||||
// if (event.total > 0) {
|
||||
// percent = (event.loaded / event.total) * 100;
|
||||
// }
|
||||
// onProgress(parseInt(String(percent), 10), event);
|
||||
// };
|
||||
|
||||
// try {
|
||||
// // https://github.com/axios/axios/issues/1630
|
||||
// // https://github.com/nuysoft/Mock/issues/127
|
||||
|
||||
// const res = await userUploadApi(formData, {
|
||||
// controller,
|
||||
// onUploadProgress,
|
||||
// });
|
||||
// onSuccess(res);
|
||||
// } catch (error) {
|
||||
// onError(error);
|
||||
// }
|
||||
// })();
|
||||
// return {
|
||||
// abort() {
|
||||
// controller.abort();
|
||||
// },
|
||||
// };
|
||||
// };
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
Loading…
Reference in New Issue
Block a user