mirror of
https://github.com/Tencent/tdesign-vue-next-starter.git
synced 2024-12-23 09:29:50 +08:00
chore: sync main for develop
chore: sync main for develop
This commit is contained in:
commit
95039ea680
|
@ -1,2 +1,11 @@
|
||||||
// commit-lint config
|
// commit-lint config
|
||||||
module.exports = { extends: ['@commitlint/config-conventional'] };
|
module.exports = {
|
||||||
|
extends: ['@commitlint/config-conventional'],
|
||||||
|
rules: {
|
||||||
|
'type-enum': [
|
||||||
|
2,
|
||||||
|
'always',
|
||||||
|
['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'types'],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
16
package.json
16
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "tdesign-vue-next-starter",
|
"name": "@tencent/tdesign-vue-next-starter",
|
||||||
"version": "0.7.5",
|
"version": "0.7.6",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:mock": "vite --open --mode mock",
|
"dev:mock": "vite --open --mode mock",
|
||||||
"dev": "vite --open --mode development",
|
"dev": "vite --open --mode development",
|
||||||
|
@ -28,9 +28,9 @@
|
||||||
"pinia-plugin-persistedstate": "^3.1.0",
|
"pinia-plugin-persistedstate": "^3.1.0",
|
||||||
"qrcode.vue": "^3.3.4",
|
"qrcode.vue": "^3.3.4",
|
||||||
"qs": "^6.11.1",
|
"qs": "^6.11.1",
|
||||||
"tdesign-icons-vue-next": "^0.1.8",
|
"tdesign-icons-vue-next": "^0.1.11",
|
||||||
"tdesign-vue-next": "^1.2.2",
|
"tdesign-vue-next": "^1.3.4",
|
||||||
"tvision-color": "^1.5.0",
|
"tvision-color": "^1.6.0",
|
||||||
"vue": "^3.2.47",
|
"vue": "^3.2.47",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-router": "~4.1.6"
|
"vue-router": "~4.1.6"
|
||||||
|
@ -83,12 +83,10 @@
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{js,jsx,vue,ts,tsx}": [
|
"*.{js,jsx,vue,ts,tsx}": [
|
||||||
"prettier --write",
|
"prettier --write",
|
||||||
"npm run lint:fix",
|
"npm run lint:fix"
|
||||||
"git add ."
|
|
||||||
],
|
],
|
||||||
"*.{html,vue,vss,sass,less}": [
|
"*.{html,vue,vss,sass,less}": [
|
||||||
"npm run stylelint:fix",
|
"npm run stylelint:fix"
|
||||||
"git add ."
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
export const prefix = 'tdesign-starter';
|
export const prefix = 'tdesign-starter';
|
||||||
export const TOKEN_NAME = 'tdesign-starter';
|
|
||||||
|
|
|
@ -34,12 +34,14 @@ export const CONTRACT_PAYMENT_TYPES = {
|
||||||
RECEIPT: 1,
|
RECEIPT: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 通知的优先级对应的TAG类型
|
// 标签类型
|
||||||
export const NOTIFICATION_TYPES = {
|
type TagTheme = 'default' | 'success' | 'primary' | 'warning' | 'danger';
|
||||||
low: 'primary',
|
// 通知的优先级对应的标签类型
|
||||||
middle: 'warning',
|
export const NOTIFICATION_TYPES: Map<string, TagTheme> = new Map([
|
||||||
high: 'danger',
|
['low', 'primary'],
|
||||||
};
|
['middle', 'warning'],
|
||||||
|
['high', 'danger'],
|
||||||
|
]);
|
||||||
|
|
||||||
// 通用请求头
|
// 通用请求头
|
||||||
export enum ContentTypeEnum {
|
export enum ContentTypeEnum {
|
||||||
|
|
|
@ -39,7 +39,7 @@ export const useChart = (domId: string): Ref<echarts.ECharts> => {
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const useCounter = (duration = 60): [Ref<number>, () => void] => {
|
export const useCounter = (duration = 60): [Ref<number>, () => void] => {
|
||||||
let intervalTimer;
|
let intervalTimer: ReturnType<typeof setInterval>;
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
clearInterval(intervalTimer);
|
clearInterval(intervalTimer);
|
||||||
});
|
});
|
||||||
|
|
|
@ -141,7 +141,7 @@ const changeCollapsed = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNav = (url) => {
|
const handleNav = (url: string) => {
|
||||||
router.push(url);
|
router.push(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
:min-column-width="128"
|
:min-column-width="128"
|
||||||
:popup-props="{
|
:popup-props="{
|
||||||
overlayClassName: 'route-tabs-dropdown',
|
overlayClassName: 'route-tabs-dropdown',
|
||||||
onVisibleChange: (visible, ctx) => handleTabMenuClick(visible, ctx, routeItem.path),
|
onVisibleChange: (visible: boolean, ctx: PopupVisibleChangeContext) => handleTabMenuClick(visible, ctx, routeItem.path),
|
||||||
visible: activeTabPath === routeItem.path,
|
visible: activeTabPath === routeItem.path,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
@ -70,12 +70,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { PopupVisibleChangeContext } from 'tdesign-vue-next';
|
||||||
import { computed, nextTick, ref } from 'vue';
|
import { computed, nextTick, ref } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
import { prefix } from '@/config/global';
|
import { prefix } from '@/config/global';
|
||||||
import { useSettingStore, useTabsRouterStore } from '@/store';
|
import { useSettingStore, useTabsRouterStore } from '@/store';
|
||||||
import type { TRouterInfo } from '@/types/interface';
|
import type { TRouterInfo, TTabRemoveOptions } from '@/types/interface';
|
||||||
|
|
||||||
import LBreadcrumb from './Breadcrumb.vue';
|
import LBreadcrumb from './Breadcrumb.vue';
|
||||||
import LContent from './Content.vue';
|
import LContent from './Content.vue';
|
||||||
|
@ -95,12 +96,12 @@ const handleChangeCurrentTab = (path: string) => {
|
||||||
router.push({ path, query: route.query });
|
router.push({ path, query: route.query });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemove = ({ value: path, index }) => {
|
const handleRemove = (options: TTabRemoveOptions) => {
|
||||||
const { tabRouters } = tabsRouterStore;
|
const { tabRouters } = tabsRouterStore;
|
||||||
const nextRouter = tabRouters[index + 1] || tabRouters[index - 1];
|
const nextRouter = tabRouters[options.index + 1] || tabRouters[options.index - 1];
|
||||||
|
|
||||||
tabsRouterStore.subtractCurrentTabRouter({ path, routeIdx: index });
|
tabsRouterStore.subtractCurrentTabRouter({ path: options.value as string, routeIdx: options.index });
|
||||||
if (path === route.path) router.push({ path: nextRouter.path, query: nextRouter.query });
|
if ((options.value as string) === route.path) router.push({ path: nextRouter.path, query: nextRouter.query });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRefresh = (route: TRouterInfo, routeIdx: number) => {
|
const handleRefresh = (route: TRouterInfo, routeIdx: number) => {
|
||||||
|
@ -147,7 +148,7 @@ const handleOperationEffect = (type: 'other' | 'ahead' | 'behind', routeIndex: n
|
||||||
|
|
||||||
activeTabPath.value = null;
|
activeTabPath.value = null;
|
||||||
};
|
};
|
||||||
const handleTabMenuClick = (visible: boolean, ctx, path: string) => {
|
const handleTabMenuClick = (visible: boolean, ctx: PopupVisibleChangeContext, path: string) => {
|
||||||
if (ctx.trigger === 'document') activeTabPath.value = null;
|
if (ctx.trigger === 'document') activeTabPath.value = null;
|
||||||
if (visible) activeTabPath.value = path;
|
if (visible) activeTabPath.value = path;
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { computed } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import { usePermissionStore, useSettingStore } from '@/store';
|
import { usePermissionStore, useSettingStore } from '@/store';
|
||||||
|
import type { MenuRoute } from '@/types/interface';
|
||||||
|
|
||||||
import LSideNav from './SideNav.vue';
|
import LSideNav from './SideNav.vue';
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ const { routers: menuRouters } = storeToRefs(permissionStore);
|
||||||
|
|
||||||
const sideMenu = computed(() => {
|
const sideMenu = computed(() => {
|
||||||
const { layout, splitMenu } = settingStore;
|
const { layout, splitMenu } = settingStore;
|
||||||
let newMenuRouters = menuRouters.value;
|
let newMenuRouters = menuRouters.value as Array<MenuRoute>;
|
||||||
if (layout === 'mix' && splitMenu) {
|
if (layout === 'mix' && splitMenu) {
|
||||||
newMenuRouters.forEach((menu) => {
|
newMenuRouters.forEach((menu) => {
|
||||||
if (route.path.indexOf(menu.path) === 0) {
|
if (route.path.indexOf(menu.path) === 0) {
|
||||||
|
|
|
@ -120,7 +120,7 @@ const initStyleConfig = () => {
|
||||||
const styleConfig = STYLE_CONFIG;
|
const styleConfig = STYLE_CONFIG;
|
||||||
for (const key in styleConfig) {
|
for (const key in styleConfig) {
|
||||||
if (Object.prototype.hasOwnProperty.call(styleConfig, key)) {
|
if (Object.prototype.hasOwnProperty.call(styleConfig, key)) {
|
||||||
styleConfig[key] = settingStore[key];
|
(styleConfig[key as keyof typeof STYLE_CONFIG] as any) = settingStore[key as keyof typeof STYLE_CONFIG];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { EChartsOption } from 'echarts';
|
||||||
|
|
||||||
import { TChartColor } from '@/config/color';
|
import { TChartColor } from '@/config/color';
|
||||||
import { getRandomArray } from '@/utils/charts';
|
import { getRandomArray } from '@/utils/charts';
|
||||||
|
@ -307,7 +308,7 @@ export function getPieChartDataSet({
|
||||||
textColor,
|
textColor,
|
||||||
placeholderColor,
|
placeholderColor,
|
||||||
containerColor,
|
containerColor,
|
||||||
}: { radius?: number } & Record<string, string>) {
|
}: { radius?: number } & Record<string, string>): EChartsOption {
|
||||||
return {
|
return {
|
||||||
color: getChartListColor(),
|
color: getChartListColor(),
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
|
|
@ -83,14 +83,14 @@ export const TABLE_COLUMNS_DATA = [
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
colKey: 'index',
|
colKey: 'index',
|
||||||
title: '申请号',
|
title: '申请号',
|
||||||
sorter: (a, b) => a.index.substr(3) - b.index.substr(3),
|
sorter: (a: any, b: any) => a.index.substr(3) - b.index.substr(3),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: 200,
|
width: 200,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
colKey: 'pdName',
|
colKey: 'pdName',
|
||||||
title: '产品名称',
|
title: '产品名称',
|
||||||
sorter: (a, b) => a.pdName.length - b.pdName.length,
|
sorter: (a: any, b: any) => a.pdName.length - b.pdName.length,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: 200,
|
width: 200,
|
||||||
|
@ -103,7 +103,7 @@ export const TABLE_COLUMNS_DATA = [
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
colKey: 'purchaseNum',
|
colKey: 'purchaseNum',
|
||||||
title: '采购数量',
|
title: '采购数量',
|
||||||
sorter: (a, b) => a.purchaseNum - b.purchaseNum,
|
sorter: (a: any, b: any) => a.purchaseNum - b.purchaseNum,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: 160,
|
width: 160,
|
||||||
|
@ -116,7 +116,7 @@ export const TABLE_COLUMNS_DATA = [
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
colKey: 'updateTime',
|
colKey: 'updateTime',
|
||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
sorter: (a, b) => Date.parse(a.updateTime) - Date.parse(b.updateTime),
|
sorter: (a: any, b: any) => Date.parse(a.updateTime) - Date.parse(b.updateTime),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left' as const,
|
align: 'left' as const,
|
||||||
|
|
|
@ -170,16 +170,16 @@ onMounted(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const sortChange = (val) => {
|
const sortChange = (val: unknown) => {
|
||||||
console.log(val);
|
console.log(val);
|
||||||
};
|
};
|
||||||
const rehandleChange = (changeParams, triggerAndData) => {
|
const rehandleChange = (changeParams: unknown, triggerAndData: unknown) => {
|
||||||
console.log('统一Change', changeParams, triggerAndData);
|
console.log('统一Change', changeParams, triggerAndData);
|
||||||
};
|
};
|
||||||
const listClick = () => {
|
const listClick = () => {
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
};
|
};
|
||||||
const deleteClickOp = (columns) => {
|
const deleteClickOp = (columns: { rowIndex: number }) => {
|
||||||
data.value.splice(columns.rowIndex, 1);
|
data.value.splice(columns.rowIndex, 1);
|
||||||
};
|
};
|
||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
|
|
|
@ -87,7 +87,7 @@ export const TABLE_COLUMNS = [
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
colKey: 'name',
|
colKey: 'name',
|
||||||
title: '项目名称',
|
title: '项目名称',
|
||||||
sorter: (a, b) => a.name.substr(10) - b.name.substr(10),
|
sorter: (a: any, b: any) => a.name.substr(10) - b.name.substr(10),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: '280',
|
width: '280',
|
||||||
|
@ -101,7 +101,7 @@ export const TABLE_COLUMNS = [
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
colKey: 'updateTime',
|
colKey: 'updateTime',
|
||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
sorter: (a, b) => Date.parse(a.updateTime) - Date.parse(b.updateTime),
|
sorter: (a: any, b: any) => Date.parse(a.updateTime) - Date.parse(b.updateTime),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left' as const,
|
align: 'left' as const,
|
||||||
|
|
|
@ -147,8 +147,6 @@ onMounted(() => {
|
||||||
dataChart.setOption(get2ColBarChartDataSet({ ...chartColors.value }));
|
dataChart.setOption(get2ColBarChartDataSet({ ...chartColors.value }));
|
||||||
});
|
});
|
||||||
|
|
||||||
const intervalTimer = null;
|
|
||||||
|
|
||||||
/// / chartSize update
|
/// / chartSize update
|
||||||
const updateContainer = () => {
|
const updateContainer = () => {
|
||||||
monitorChart.resize({
|
monitorChart.resize({
|
||||||
|
@ -163,7 +161,6 @@ const updateContainer = () => {
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
window.removeEventListener('resize', updateContainer);
|
window.removeEventListener('resize', updateContainer);
|
||||||
clearInterval(intervalTimer);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const onAlertChange = () => {
|
const onAlertChange = () => {
|
||||||
|
@ -182,10 +179,10 @@ watch(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const sortChange = (val) => {
|
const sortChange = (val: unknown) => {
|
||||||
console.log(val);
|
console.log(val);
|
||||||
};
|
};
|
||||||
const rehandleChange = (changeParams, triggerAndData) => {
|
const rehandleChange = (changeParams: unknown, triggerAndData: unknown) => {
|
||||||
console.log('统一Change', changeParams, triggerAndData);
|
console.log('统一Change', changeParams, triggerAndData);
|
||||||
};
|
};
|
||||||
const listClick = () => {
|
const listClick = () => {
|
||||||
|
@ -194,7 +191,7 @@ const listClick = () => {
|
||||||
const onConfirm = () => {
|
const onConfirm = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
};
|
};
|
||||||
const deleteClickOp = (e) => {
|
const deleteClickOp = (e: { rowIndex: number }) => {
|
||||||
data.value.splice(e.rowIndex, 1);
|
data.value.splice(e.rowIndex, 1);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<t-list v-if="msgDataList.length > 0" class="secondary-msg-list" :split="true">
|
<t-list v-if="msgDataList.length > 0" class="secondary-msg-list" :split="true">
|
||||||
<t-list-item v-for="(item, index) in msgDataList" :key="index">
|
<t-list-item v-for="(item, index) in msgDataList" :key="index">
|
||||||
<p :class="['content', { unread: item.status }]" @click="setReadStatus(item)">
|
<p :class="['content', { unread: item.status }]" @click="setReadStatus(item)">
|
||||||
<t-tag size="medium" :theme="NOTIFICATION_TYPES[item.quality]" variant="light">
|
<t-tag size="medium" :theme="NOTIFICATION_TYPES.get(item.quality)" variant="light">
|
||||||
{{ item.type }}
|
{{ item.type }}
|
||||||
</t-tag>
|
</t-tag>
|
||||||
{{ item.content }}
|
{{ item.content }}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { FormRule } from 'tdesign-vue-next';
|
import type { FormRule, UploadFile } from 'tdesign-vue-next';
|
||||||
|
|
||||||
export const FORM_RULES: Record<string, FormRule[]> = {
|
export const FORM_RULES: Record<string, FormRule[]> = {
|
||||||
name: [{ required: true, message: '请输入合同名称', type: 'error' }],
|
name: [{ required: true, message: '请输入合同名称', type: 'error' }],
|
||||||
|
@ -23,7 +23,7 @@ export const INITIAL_DATA = {
|
||||||
payment: '1',
|
payment: '1',
|
||||||
amount: 0,
|
amount: 0,
|
||||||
comment: '',
|
comment: '',
|
||||||
files: [],
|
files: [] as Array<UploadFile>,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TYPE_OPTIONS = [
|
export const TYPE_OPTIONS = [
|
||||||
|
|
|
@ -164,6 +164,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { SubmitContext, UploadFailContext, UploadFile } from 'tdesign-vue-next';
|
||||||
import { MessagePlugin } from 'tdesign-vue-next';
|
import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
@ -174,12 +175,12 @@ const formData = ref({ ...INITIAL_DATA });
|
||||||
const onReset = () => {
|
const onReset = () => {
|
||||||
MessagePlugin.warning('取消新建');
|
MessagePlugin.warning('取消新建');
|
||||||
};
|
};
|
||||||
const onSubmit = ({ validateResult }) => {
|
const onSubmit = (ctx: SubmitContext) => {
|
||||||
if (validateResult === true) {
|
if (ctx.validateResult === true) {
|
||||||
MessagePlugin.success('新建成功');
|
MessagePlugin.success('新建成功');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const beforeUpload = (file) => {
|
const beforeUpload = (file: UploadFile) => {
|
||||||
if (!/\.(pdf)$/.test(file.name)) {
|
if (!/\.(pdf)$/.test(file.name)) {
|
||||||
MessagePlugin.warning('请上传pdf文件');
|
MessagePlugin.warning('请上传pdf文件');
|
||||||
return false;
|
return false;
|
||||||
|
@ -190,11 +191,11 @@ const beforeUpload = (file) => {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
const handleFail = ({ file }) => {
|
const handleFail = (options: UploadFailContext) => {
|
||||||
MessagePlugin.error(`文件 ${file.name} 上传失败`);
|
MessagePlugin.error(`文件 ${options.file.name} 上传失败`);
|
||||||
};
|
};
|
||||||
// 用于格式化接口响应值,error 会被用于上传失败的提示文字;url 表示文件/图片地址
|
// 用于格式化接口响应值,error 会被用于上传失败的提示文字;url 表示文件/图片地址
|
||||||
const formatResponse = (res) => {
|
const formatResponse = (res: any) => {
|
||||||
return { ...res, error: '上传失败,请重试', url: res.url };
|
return { ...res, error: '上传失败,请重试', url: res.url };
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
:data="formData1"
|
:data="formData1"
|
||||||
:rules="FORM_RULES"
|
:rules="FORM_RULES"
|
||||||
label-align="right"
|
label-align="right"
|
||||||
@submit="(result) => onSubmit(result, 1)"
|
@submit="(result: SubmitContext) => onSubmit(result, 1)"
|
||||||
>
|
>
|
||||||
<t-form-item label="合同名称" name="name">
|
<t-form-item label="合同名称" name="name">
|
||||||
<t-select v-model="formData1.name" :style="{ width: '480px' }" class="demo-select-base" clearable>
|
<t-select v-model="formData1.name" :style="{ width: '480px' }" class="demo-select-base" clearable>
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
:rules="FORM_RULES"
|
:rules="FORM_RULES"
|
||||||
label-align="left"
|
label-align="left"
|
||||||
@reset="onReset(0)"
|
@reset="onReset(0)"
|
||||||
@submit="(result) => onSubmit(result, 2)"
|
@submit="(result: SubmitContext) => onSubmit(result, 2)"
|
||||||
>
|
>
|
||||||
<t-form-item label="发票抬头" name="title">
|
<t-form-item label="发票抬头" name="title">
|
||||||
<t-input v-model="formData2.title" :style="{ width: '480px' }" placeholder="请输入发票抬头" />
|
<t-input v-model="formData2.title" :style="{ width: '480px' }" placeholder="请输入发票抬头" />
|
||||||
|
@ -96,7 +96,7 @@
|
||||||
:rules="FORM_RULES"
|
:rules="FORM_RULES"
|
||||||
label-align="left"
|
label-align="left"
|
||||||
@reset="onReset(1)"
|
@reset="onReset(1)"
|
||||||
@submit="(result) => onSubmit(result, 6)"
|
@submit="(result: SubmitContext) => onSubmit(result, 6)"
|
||||||
>
|
>
|
||||||
<t-form-item label="收货人" name="consignee">
|
<t-form-item label="收货人" name="consignee">
|
||||||
<t-input v-model="formData3.consignee" :style="{ width: '480px' }" placeholder="请输入收货人" />
|
<t-input v-model="formData3.consignee" :style="{ width: '480px' }" placeholder="请输入收货人" />
|
||||||
|
@ -147,7 +147,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Data, SubmitContext } from 'tdesign-vue-next';
|
import { SubmitContext } from 'tdesign-vue-next';
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ const amount = computed(() => {
|
||||||
return '--';
|
return '--';
|
||||||
});
|
});
|
||||||
|
|
||||||
const onSubmit = (result: SubmitContext<Data>, val: number) => {
|
const onSubmit = (result: SubmitContext, val: number) => {
|
||||||
if (result.validateResult === true) {
|
if (result.validateResult === true) {
|
||||||
activeForm.value = val;
|
activeForm.value = val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,10 +160,10 @@ const rowKey = 'index';
|
||||||
const rehandleSelectChange = (val: number[]) => {
|
const rehandleSelectChange = (val: number[]) => {
|
||||||
selectedRowKeys.value = val;
|
selectedRowKeys.value = val;
|
||||||
};
|
};
|
||||||
const rehandlePageChange = (curr, pageInfo) => {
|
const rehandlePageChange = (curr: unknown, pageInfo: unknown) => {
|
||||||
console.log('分页变化', curr, pageInfo);
|
console.log('分页变化', curr, pageInfo);
|
||||||
};
|
};
|
||||||
const rehandleChange = (changeParams, triggerAndData) => {
|
const rehandleChange = (changeParams: unknown, triggerAndData: unknown) => {
|
||||||
console.log('统一Change', changeParams, triggerAndData);
|
console.log('统一Change', changeParams, triggerAndData);
|
||||||
};
|
};
|
||||||
const handleClickDetail = () => {
|
const handleClickDetail = () => {
|
||||||
|
|
|
@ -73,15 +73,26 @@ import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
import { computed, onMounted, ref } from 'vue';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
|
|
||||||
import { getCardList } from '@/api/list';
|
import { getCardList } from '@/api/list';
|
||||||
|
import type { CardProductType } from '@/components/product-card/index.vue';
|
||||||
import ProductCard from '@/components/product-card/index.vue';
|
import ProductCard from '@/components/product-card/index.vue';
|
||||||
|
|
||||||
import DialogForm from './components/DialogForm.vue';
|
import DialogForm from './components/DialogForm.vue';
|
||||||
|
|
||||||
const INITIAL_DATA = {
|
interface FormData {
|
||||||
|
name: string;
|
||||||
|
status: string;
|
||||||
|
description: string;
|
||||||
|
type: number;
|
||||||
|
mark: string;
|
||||||
|
amount: number;
|
||||||
|
[key: string]: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
const INITIAL_DATA: FormData = {
|
||||||
name: '',
|
name: '',
|
||||||
status: '',
|
status: '',
|
||||||
description: '',
|
description: '',
|
||||||
type: '',
|
type: 0,
|
||||||
mark: '',
|
mark: '',
|
||||||
amount: 0,
|
amount: 0,
|
||||||
};
|
};
|
||||||
|
@ -127,7 +138,7 @@ const onPageSizeChange = (size: number) => {
|
||||||
const onCurrentChange = (current: number) => {
|
const onCurrentChange = (current: number) => {
|
||||||
pagination.value.current = current;
|
pagination.value.current = current;
|
||||||
};
|
};
|
||||||
const handleDeleteItem = (product) => {
|
const handleDeleteItem = (product: CardProductType) => {
|
||||||
confirmVisible.value = true;
|
confirmVisible.value = true;
|
||||||
deleteProduct.value = product;
|
deleteProduct.value = product;
|
||||||
};
|
};
|
||||||
|
@ -141,9 +152,16 @@ const onCancel = () => {
|
||||||
deleteProduct.value = undefined;
|
deleteProduct.value = undefined;
|
||||||
formData.value = { ...INITIAL_DATA };
|
formData.value = { ...INITIAL_DATA };
|
||||||
};
|
};
|
||||||
const handleManageProduct = (product) => {
|
const handleManageProduct = (product: CardProductType) => {
|
||||||
formDialogVisible.value = true;
|
formDialogVisible.value = true;
|
||||||
formData.value = { ...product, status: product?.isSetup ? '1' : '0' };
|
formData.value = {
|
||||||
|
name: product.name,
|
||||||
|
status: product?.isSetup ? '1' : '0',
|
||||||
|
description: product.description,
|
||||||
|
type: product.type,
|
||||||
|
mark: '',
|
||||||
|
amount: 0,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ import { useSettingStore } from '@/store';
|
||||||
|
|
||||||
const store = useSettingStore();
|
const store = useSettingStore();
|
||||||
|
|
||||||
const COLUMNS: PrimaryTableCol<TableRowData>[] = [
|
const COLUMNS: PrimaryTableCol[] = [
|
||||||
{
|
{
|
||||||
title: '合同名称',
|
title: '合同名称',
|
||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
|
@ -167,8 +167,8 @@ const COLUMNS: PrimaryTableCol<TableRowData>[] = [
|
||||||
|
|
||||||
const searchForm = {
|
const searchForm = {
|
||||||
name: '',
|
name: '',
|
||||||
no: undefined,
|
no: '',
|
||||||
status: undefined,
|
status: typeof CONTRACT_STATUS,
|
||||||
type: '',
|
type: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -233,24 +233,24 @@ onMounted(() => {
|
||||||
fetchData();
|
fetchData();
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleClickDelete = ({ row }) => {
|
const handleClickDelete = (slot: { row: { rowIndex: number } }) => {
|
||||||
deleteIdx.value = row.rowIndex;
|
deleteIdx.value = slot.row.rowIndex;
|
||||||
confirmVisible.value = true;
|
confirmVisible.value = true;
|
||||||
};
|
};
|
||||||
const onReset = (val) => {
|
const onReset = (val: unknown) => {
|
||||||
console.log(val);
|
console.log(val);
|
||||||
};
|
};
|
||||||
const onSubmit = (val) => {
|
const onSubmit = (val: unknown) => {
|
||||||
console.log(val);
|
console.log(val);
|
||||||
};
|
};
|
||||||
const rehandlePageChange = (pageInfo: PageInfo, newDataSource: TableRowData[]) => {
|
const rehandlePageChange = (pageInfo: PageInfo, newDataSource: TableRowData[]) => {
|
||||||
console.log('分页变化', pageInfo, newDataSource);
|
console.log('分页变化', pageInfo, newDataSource);
|
||||||
};
|
};
|
||||||
const rehandleChange = (changeParams, triggerAndData) => {
|
const rehandleChange = (changeParams: unknown, triggerAndData: unknown) => {
|
||||||
console.log('统一Change', changeParams, triggerAndData);
|
console.log('统一Change', changeParams, triggerAndData);
|
||||||
};
|
};
|
||||||
const rehandleClickOp = ({ text, row }) => {
|
const rehandleClickOp = (ctx: unknown) => {
|
||||||
console.log(text, row);
|
console.log(ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
const headerAffixedTop = computed(
|
const headerAffixedTop = computed(
|
||||||
|
|
|
@ -24,6 +24,7 @@ export default {
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { SearchIcon } from 'tdesign-icons-vue-next';
|
import { SearchIcon } from 'tdesign-icons-vue-next';
|
||||||
|
import type { TreeNodeModel } from 'tdesign-vue-next';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
import CommonTable from '../components/CommonTable.vue';
|
import CommonTable from '../components/CommonTable.vue';
|
||||||
|
@ -35,9 +36,8 @@ const filterText = ref();
|
||||||
const expanded = ['0', '0-0', '0-1', '0-2', '0-3', '0-4'];
|
const expanded = ['0', '0-0', '0-1', '0-2', '0-3', '0-4'];
|
||||||
|
|
||||||
const onInput = () => {
|
const onInput = () => {
|
||||||
filterByText.value = (node) => {
|
filterByText.value = (node: TreeNodeModel) => {
|
||||||
const rs = node.label.indexOf(filterText.value) >= 0;
|
return node.label.indexOf(filterText.value) >= 0;
|
||||||
return rs;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import QrcodeVue from 'qrcode.vue';
|
import QrcodeVue from 'qrcode.vue';
|
||||||
import type { FormInstanceFunctions, FormRule } from 'tdesign-vue-next';
|
import type { FormInstanceFunctions, FormRule, SubmitContext } from 'tdesign-vue-next';
|
||||||
import { MessagePlugin } from 'tdesign-vue-next';
|
import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
@ -131,8 +131,8 @@ const sendCode = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async ({ validateResult }) => {
|
const onSubmit = async (ctx: SubmitContext) => {
|
||||||
if (validateResult === true) {
|
if (ctx.validateResult === true) {
|
||||||
try {
|
try {
|
||||||
await userStore.login(formData.value);
|
await userStore.login(formData.value);
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { FormRule, MessagePlugin } from 'tdesign-vue-next';
|
import type { FormRule, SubmitContext } from 'tdesign-vue-next';
|
||||||
|
import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
import { useCounter } from '@/hooks';
|
import { useCounter } from '@/hooks';
|
||||||
|
@ -105,8 +106,8 @@ const [countDown, handleCounter] = useCounter();
|
||||||
|
|
||||||
const emit = defineEmits(['registerSuccess']);
|
const emit = defineEmits(['registerSuccess']);
|
||||||
|
|
||||||
const onSubmit = ({ validateResult }) => {
|
const onSubmit = (ctx: SubmitContext) => {
|
||||||
if (validateResult === true) {
|
if (ctx.validateResult === true) {
|
||||||
if (!formData.value.checked) {
|
if (!formData.value.checked) {
|
||||||
MessagePlugin.error('请同意TDesign服务协议和TDesign 隐私声明');
|
MessagePlugin.error('请同意TDesign服务协议和TDesign 隐私声明');
|
||||||
return;
|
return;
|
||||||
|
@ -116,7 +117,7 @@ const onSubmit = ({ validateResult }) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const switchType = (val) => {
|
const switchType = (val: string) => {
|
||||||
form.value.reset();
|
form.value.reset();
|
||||||
type.value = val;
|
type.value = val;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
export const USER_INFO_LIST = [
|
export interface UserInfoListType {
|
||||||
|
title: string;
|
||||||
|
content: string;
|
||||||
|
span?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const USER_INFO_LIST: Array<UserInfoListType> = [
|
||||||
{
|
{
|
||||||
title: '手机',
|
title: '手机',
|
||||||
content: '+86 13923734567',
|
content: '+86 13923734567',
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
</t-button>
|
</t-button>
|
||||||
</template>
|
</template>
|
||||||
<t-row class="content" justify="space-between">
|
<t-row class="content" justify="space-between">
|
||||||
<t-col v-for="(item, index) in USER_INFO_LIST" :key="index" class="contract" :span="item.span || 3">
|
<t-col v-for="(item, index) in USER_INFO_LIST" :key="index" class="contract" :span="item.span ?? 3">
|
||||||
<div class="contract-title">
|
<div class="contract-title">
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -98,6 +98,7 @@ import { LineChart } from 'echarts/charts';
|
||||||
import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components';
|
import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components';
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import { CanvasRenderer } from 'echarts/renderers';
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
|
import type { DateRangeValue } from 'tdesign-vue-next';
|
||||||
import { computed, nextTick, onMounted, onUnmounted, watch } from 'vue';
|
import { computed, nextTick, onMounted, onUnmounted, watch } from 'vue';
|
||||||
|
|
||||||
import ProductAIcon from '@/assets/assets-product-1.svg';
|
import ProductAIcon from '@/assets/assets-product-1.svg';
|
||||||
|
@ -118,8 +119,13 @@ let lineChart: echarts.ECharts;
|
||||||
const store = useSettingStore();
|
const store = useSettingStore();
|
||||||
const chartColors = computed(() => store.chartColors);
|
const chartColors = computed(() => store.chartColors);
|
||||||
|
|
||||||
const onLineChange = (value) => {
|
const onLineChange = (value: DateRangeValue) => {
|
||||||
lineChart.setOption(getFolderLineDataSet(value));
|
lineChart.setOption(
|
||||||
|
getFolderLineDataSet({
|
||||||
|
dateTime: value as string[],
|
||||||
|
...chartColors.value,
|
||||||
|
}),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const initChart = () => {
|
const initChart = () => {
|
||||||
|
@ -154,7 +160,7 @@ onUnmounted(() => {
|
||||||
window.removeEventListener('resize', updateContainer);
|
window.removeEventListener('resize', updateContainer);
|
||||||
});
|
});
|
||||||
|
|
||||||
const getIcon = (type) => {
|
const getIcon = (type: string) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'a':
|
case 'a':
|
||||||
return ProductAIcon;
|
return ProductAIcon;
|
||||||
|
|
|
@ -4,9 +4,8 @@ import NProgress from 'nprogress'; // progress bar
|
||||||
import { MessagePlugin } from 'tdesign-vue-next';
|
import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
import { TOKEN_NAME } from '@/config/global';
|
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import { getPermissionStore, getUserStore } from '@/store';
|
import { getPermissionStore, useUserStore } from '@/store';
|
||||||
import { PAGE_NOT_FOUND_ROUTE } from '@/utils/route/constant';
|
import { PAGE_NOT_FOUND_ROUTE } from '@/utils/route/constant';
|
||||||
|
|
||||||
NProgress.configure({ showSpinner: false });
|
NProgress.configure({ showSpinner: false });
|
||||||
|
@ -17,9 +16,9 @@ router.beforeEach(async (to, from, next) => {
|
||||||
const permissionStore = getPermissionStore();
|
const permissionStore = getPermissionStore();
|
||||||
const { whiteListRouters } = permissionStore;
|
const { whiteListRouters } = permissionStore;
|
||||||
|
|
||||||
const userStore = getUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
if (userStore[TOKEN_NAME]) {
|
if (userStore.token) {
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
|
@ -73,7 +72,7 @@ router.beforeEach(async (to, from, next) => {
|
||||||
|
|
||||||
router.afterEach((to) => {
|
router.afterEach((to) => {
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
const userStore = getUserStore();
|
const userStore = useUserStore();
|
||||||
const permissionStore = getPermissionStore();
|
const permissionStore = getPermissionStore();
|
||||||
|
|
||||||
userStore.logout();
|
userStore.logout();
|
||||||
|
|
|
@ -40,7 +40,7 @@ export function mapModuleRouterList(modules: Record<string, unknown>): Array<Rou
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getRoutesExpanded = () => {
|
export const getRoutesExpanded = () => {
|
||||||
const expandedRoutes = [];
|
const expandedRoutes: Array<string> = [];
|
||||||
|
|
||||||
fixedRouterList.forEach((item) => {
|
fixedRouterList.forEach((item) => {
|
||||||
if (item.meta && item.meta.expanded) {
|
if (item.meta && item.meta.expanded) {
|
||||||
|
|
|
@ -8,10 +8,10 @@ import router, { allRoutes } from '@/router';
|
||||||
import { store } from '@/store';
|
import { store } from '@/store';
|
||||||
|
|
||||||
function filterPermissionsRouters(routes: Array<RouteRecordRaw>, roles: Array<unknown>) {
|
function filterPermissionsRouters(routes: Array<RouteRecordRaw>, roles: Array<unknown>) {
|
||||||
const res = [];
|
const res: Array<RouteRecordRaw> = [];
|
||||||
const removeRoutes = [];
|
const removeRoutes: Array<RouteRecordRaw> = [];
|
||||||
routes.forEach((route) => {
|
routes.forEach((route) => {
|
||||||
const children = [];
|
const children: Array<RouteRecordRaw> = [];
|
||||||
route.children?.forEach((childRouter) => {
|
route.children?.forEach((childRouter) => {
|
||||||
const roleCode = childRouter.meta?.roleCode || childRouter.name;
|
const roleCode = childRouter.meta?.roleCode || childRouter.name;
|
||||||
if (roles.indexOf(roleCode) !== -1) {
|
if (roles.indexOf(roleCode) !== -1) {
|
||||||
|
@ -38,7 +38,7 @@ export const usePermissionStore = defineStore('permission', {
|
||||||
async initRoutes(roles: Array<unknown>) {
|
async initRoutes(roles: Array<unknown>) {
|
||||||
let accessedRouters = [];
|
let accessedRouters = [];
|
||||||
|
|
||||||
let removeRoutes = [];
|
let removeRoutes: Array<RouteRecordRaw> = [];
|
||||||
// special token
|
// special token
|
||||||
if (roles.includes('all')) {
|
if (roles.includes('all')) {
|
||||||
accessedRouters = allRoutes;
|
accessedRouters = allRoutes;
|
||||||
|
|
|
@ -15,6 +15,7 @@ const state = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TState = typeof state;
|
export type TState = typeof state;
|
||||||
|
export type TStateKey = keyof typeof state;
|
||||||
|
|
||||||
export const useSettingStore = defineStore('setting', {
|
export const useSettingStore = defineStore('setting', {
|
||||||
state: () => state,
|
state: () => state,
|
||||||
|
@ -72,8 +73,8 @@ export const useSettingStore = defineStore('setting', {
|
||||||
},
|
},
|
||||||
updateConfig(payload: Partial<TState>) {
|
updateConfig(payload: Partial<TState>) {
|
||||||
for (const key in payload) {
|
for (const key in payload) {
|
||||||
if (payload[key] !== undefined) {
|
if (payload[key as TStateKey] !== undefined) {
|
||||||
this[key] = payload[key];
|
this[key] = payload[key as TStateKey];
|
||||||
}
|
}
|
||||||
if (key === 'mode') {
|
if (key === 'mode') {
|
||||||
this.changeMode(payload[key]);
|
this.changeMode(payload[key]);
|
||||||
|
|
|
@ -36,7 +36,8 @@ export const useTabsRouterStore = defineStore('tabsRouter', {
|
||||||
},
|
},
|
||||||
// 处理新增
|
// 处理新增
|
||||||
appendTabRouterList(newRoute: TRouterInfo) {
|
appendTabRouterList(newRoute: TRouterInfo) {
|
||||||
const needAlive = !ignoreCacheRoutes.includes(newRoute.name as string);
|
// 不要将判断条件newRoute.meta.keepAlive !== false修改为newRoute.meta.keepAlive,starter默认开启保活,所以meta.keepAlive未定义时也需要进行保活,只有显式说明false才禁用保活。
|
||||||
|
const needAlive = !ignoreCacheRoutes.includes(newRoute.name as string) && newRoute.meta?.keepAlive !== false;
|
||||||
if (!this.tabRouters.find((route: TRouterInfo) => route.path === newRoute.path)) {
|
if (!this.tabRouters.find((route: TRouterInfo) => route.path === newRoute.path)) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
this.tabRouterList = this.tabRouterList.concat({ ...newRoute, isAlive: needAlive });
|
this.tabRouterList = this.tabRouterList.concat({ ...newRoute, isAlive: needAlive });
|
||||||
|
@ -50,7 +51,7 @@ export const useTabsRouterStore = defineStore('tabsRouter', {
|
||||||
// 处理关闭右侧
|
// 处理关闭右侧
|
||||||
subtractTabRouterBehind(newRoute: TRouterInfo) {
|
subtractTabRouterBehind(newRoute: TRouterInfo) {
|
||||||
const { routeIdx } = newRoute;
|
const { routeIdx } = newRoute;
|
||||||
const homeIdx: number = this.tabRouters.findIndex((route) => route.isHome);
|
const homeIdx: number = this.tabRouters.findIndex((route: TRouterInfo) => route.isHome);
|
||||||
let tabRouterList: Array<TRouterInfo> = this.tabRouterList.slice(0, routeIdx + 1);
|
let tabRouterList: Array<TRouterInfo> = this.tabRouterList.slice(0, routeIdx + 1);
|
||||||
if (routeIdx < homeIdx) {
|
if (routeIdx < homeIdx) {
|
||||||
tabRouterList = tabRouterList.concat(homeRoute);
|
tabRouterList = tabRouterList.concat(homeRoute);
|
||||||
|
@ -60,7 +61,7 @@ export const useTabsRouterStore = defineStore('tabsRouter', {
|
||||||
// 处理关闭左侧
|
// 处理关闭左侧
|
||||||
subtractTabRouterAhead(newRoute: TRouterInfo) {
|
subtractTabRouterAhead(newRoute: TRouterInfo) {
|
||||||
const { routeIdx } = newRoute;
|
const { routeIdx } = newRoute;
|
||||||
const homeIdx: number = this.tabRouters.findIndex((route) => route.isHome);
|
const homeIdx: number = this.tabRouters.findIndex((route: TRouterInfo) => route.isHome);
|
||||||
let tabRouterList: Array<TRouterInfo> = this.tabRouterList.slice(routeIdx);
|
let tabRouterList: Array<TRouterInfo> = this.tabRouterList.slice(routeIdx);
|
||||||
if (routeIdx > homeIdx) {
|
if (routeIdx > homeIdx) {
|
||||||
tabRouterList = homeRoute.concat(tabRouterList);
|
tabRouterList = homeRoute.concat(tabRouterList);
|
||||||
|
@ -70,7 +71,7 @@ export const useTabsRouterStore = defineStore('tabsRouter', {
|
||||||
// 处理关闭其他
|
// 处理关闭其他
|
||||||
subtractTabRouterOther(newRoute: TRouterInfo) {
|
subtractTabRouterOther(newRoute: TRouterInfo) {
|
||||||
const { routeIdx } = newRoute;
|
const { routeIdx } = newRoute;
|
||||||
const homeIdx: number = this.tabRouters.findIndex((route) => route.isHome);
|
const homeIdx: number = this.tabRouters.findIndex((route: TRouterInfo) => route.isHome);
|
||||||
this.tabRouterList = routeIdx === homeIdx ? homeRoute : homeRoute.concat([this.tabRouterList?.[routeIdx]]);
|
this.tabRouterList = routeIdx === homeIdx ? homeRoute : homeRoute.concat([this.tabRouterList?.[routeIdx]]);
|
||||||
},
|
},
|
||||||
removeTabRouterList() {
|
removeTabRouterList() {
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
|
|
||||||
import { TOKEN_NAME } from '@/config/global';
|
import { usePermissionStore } from '@/store';
|
||||||
import { store, usePermissionStore } from '@/store';
|
import type { UserInfo } from '@/types/interface';
|
||||||
|
|
||||||
const InitUserInfo = {
|
const InitUserInfo: UserInfo = {
|
||||||
name: '', // 用户名,用于展示在页面右上角头像处
|
name: '', // 用户名,用于展示在页面右上角头像处
|
||||||
roles: [], // 前端权限模型使用 如果使用请配置modules/permission-fe.ts使用
|
roles: [], // 前端权限模型使用 如果使用请配置modules/permission-fe.ts使用
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUserStore = defineStore('user', {
|
export const useUserStore = defineStore('user', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
[TOKEN_NAME]: 'main_token', // 默认token不走权限
|
token: 'main_token', // 默认token不走权限
|
||||||
userInfo: { ...InitUserInfo },
|
userInfo: { ...InitUserInfo },
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
|
@ -49,7 +49,7 @@ export const useUserStore = defineStore('user', {
|
||||||
|
|
||||||
const res = await mockLogin(userInfo);
|
const res = await mockLogin(userInfo);
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.setToken(res.data);
|
this.token = res.data;
|
||||||
} else {
|
} else {
|
||||||
throw res;
|
throw res;
|
||||||
}
|
}
|
||||||
|
@ -67,20 +67,14 @@ export const useUserStore = defineStore('user', {
|
||||||
roles: ['UserIndex', 'DashboardBase', 'login'], // 前端权限模型使用 如果使用请配置modules/permission-fe.ts使用
|
roles: ['UserIndex', 'DashboardBase', 'login'], // 前端权限模型使用 如果使用请配置modules/permission-fe.ts使用
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
const res = await mockRemoteUserInfo(this[TOKEN_NAME]);
|
const res = await mockRemoteUserInfo(this.token);
|
||||||
|
|
||||||
this.userInfo = res;
|
this.userInfo = res;
|
||||||
},
|
},
|
||||||
async logout() {
|
async logout() {
|
||||||
this.removeToken();
|
this.token = '';
|
||||||
this.userInfo = { ...InitUserInfo };
|
this.userInfo = { ...InitUserInfo };
|
||||||
},
|
},
|
||||||
async removeToken() {
|
|
||||||
this.setToken('');
|
|
||||||
},
|
|
||||||
async setToken(token: string) {
|
|
||||||
this[TOKEN_NAME] = token;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
persist: {
|
persist: {
|
||||||
afterRestore: () => {
|
afterRestore: () => {
|
||||||
|
@ -88,10 +82,6 @@ export const useUserStore = defineStore('user', {
|
||||||
permissionStore.initRoutes();
|
permissionStore.initRoutes();
|
||||||
},
|
},
|
||||||
key: 'user',
|
key: 'user',
|
||||||
paths: [TOKEN_NAME],
|
paths: ['token'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export function getUserStore() {
|
|
||||||
return useUserStore(store);
|
|
||||||
}
|
|
||||||
|
|
12
src/types/interface.d.ts
vendored
12
src/types/interface.d.ts
vendored
|
@ -1,3 +1,4 @@
|
||||||
|
import type { TabValue } from 'tdesign-vue-next';
|
||||||
import { LocationQueryRaw, RouteRecordName } from 'vue-router';
|
import { LocationQueryRaw, RouteRecordName } from 'vue-router';
|
||||||
|
|
||||||
import STYLE_CONFIG from '@/config/style';
|
import STYLE_CONFIG from '@/config/style';
|
||||||
|
@ -26,6 +27,11 @@ export type CommonObjType = {
|
||||||
[key: string]: string | number;
|
[key: string]: string | number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface UserInfo {
|
||||||
|
name: string;
|
||||||
|
roles: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface NotificationItem {
|
export interface NotificationItem {
|
||||||
id: string;
|
id: string;
|
||||||
content: string;
|
content: string;
|
||||||
|
@ -51,3 +57,9 @@ export interface TTabRouterType {
|
||||||
isRefreshing: boolean;
|
isRefreshing: boolean;
|
||||||
tabRouterList: Array<TRouterInfo>;
|
tabRouterList: Array<TRouterInfo>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TTabRemoveOptions {
|
||||||
|
value: TabValue;
|
||||||
|
index: number;
|
||||||
|
e: MouseEvent;
|
||||||
|
}
|
||||||
|
|
|
@ -3,9 +3,8 @@ import type { AxiosInstance, InternalAxiosRequestConfig } from 'axios';
|
||||||
import isString from 'lodash/isString';
|
import isString from 'lodash/isString';
|
||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
|
|
||||||
import { TOKEN_NAME } from '@/config/global';
|
|
||||||
import { ContentTypeEnum } from '@/constants';
|
import { ContentTypeEnum } from '@/constants';
|
||||||
import { getUserStore } from '@/store';
|
import { useUserStore } from '@/store';
|
||||||
|
|
||||||
import { VAxios } from './Axios';
|
import { VAxios } from './Axios';
|
||||||
import type { AxiosTransform, CreateAxiosOptions } from './AxiosTransform';
|
import type { AxiosTransform, CreateAxiosOptions } from './AxiosTransform';
|
||||||
|
@ -114,8 +113,8 @@ const transform: AxiosTransform = {
|
||||||
// 请求拦截器处理
|
// 请求拦截器处理
|
||||||
requestInterceptors: (config, options) => {
|
requestInterceptors: (config, options) => {
|
||||||
// 请求之前处理config
|
// 请求之前处理config
|
||||||
const userStore = getUserStore();
|
const userStore = useUserStore();
|
||||||
const token = userStore[TOKEN_NAME];
|
const { token } = userStore;
|
||||||
|
|
||||||
if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
|
if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
|
||||||
// jwt token
|
// jwt token
|
||||||
|
|
|
@ -44,7 +44,7 @@ export function formatRequestDate(params: Recordable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将对象转为Url参数
|
// 将对象转为Url参数
|
||||||
export function setObjToUrlParams(baseUrl: string, obj: object): string {
|
export function setObjToUrlParams(baseUrl: string, obj: { [index: string]: any }): string {
|
||||||
let parameters = '';
|
let parameters = '';
|
||||||
for (const key in obj) {
|
for (const key in obj) {
|
||||||
parameters += `${key}=${encodeURIComponent(obj[key])}&`;
|
parameters += `${key}=${encodeURIComponent(obj[key])}&`;
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["src/*"]
|
"@/*": ["src/*"]
|
||||||
}
|
},
|
||||||
|
"noImplicitAny": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"**/*.ts",
|
"**/*.ts",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user