From 787ccc59ba89bacc075562a161ecf02bc76ebadc Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 24 七月 2026 17:15:53 +0800
Subject: [PATCH] 银川 1.采购申请添加入库状态查询条件
---
FRONTEND_DEVELOPMENT.md | 311 ++++++++++++++++++++++++++-------------------------
1 files changed, 160 insertions(+), 151 deletions(-)
diff --git a/FRONTEND_DEVELOPMENT.md b/FRONTEND_DEVELOPMENT.md
index 423b6ba..367ad5a 100644
--- a/FRONTEND_DEVELOPMENT.md
+++ b/FRONTEND_DEVELOPMENT.md
@@ -12,13 +12,13 @@
```typescript
// 鉁� 姝g‘锛氱粍浠舵枃浠朵娇鐢� PascalCase
-UserList.vue
-DictTag.vue
-TableAction.vue
+UserList.vue;
+DictTag.vue;
+TableAction.vue;
// 鉂� 閿欒锛氫娇鐢� kebab-case 鎴栧叾浠栧懡鍚�
-user-list.vue
-dict_tag.vue
+user - list.vue;
+dict_tag.vue;
```
#### 缁勪欢瀹氫箟
@@ -26,7 +26,7 @@
```vue
<script lang="ts" setup>
// 鉁� 姝g‘锛氱粺涓�浣跨敤 <script setup lang="ts">
-defineOptions({ name: 'UserList' });
+defineOptions({ name: "UserList" });
// Props 瀹氫箟
interface Props {
@@ -35,13 +35,13 @@
}
const props = withDefaults(defineProps<Props>(), {
- userName: '',
+ userName: "",
});
// Emits 瀹氫箟
interface Emits {
- (e: 'update', value: string): void;
- (e: 'delete', id: number): void;
+ (e: "update", value: string): void;
+ (e: "delete", id: number): void;
}
const emit = defineEmits<Emits>();
@@ -68,10 +68,10 @@
}
// 鉁� 姝g‘锛氫娇鐢� import type 瀵煎叆绫诲瀷
-import type { UserInfo } from '#/api/system/user';
+import type { UserInfo } from "#/api/system/user";
// 鉂� 閿欒锛氭櫘閫氬鍏ョ被鍨�
-import { UserInfo } from '#/api/system/user';
+import { UserInfo } from "#/api/system/user";
```
### 1.2 鐩綍缁撴瀯瑙勮寖
@@ -105,7 +105,7 @@
```typescript
// src/api/system/user/index.ts
-import { request } from '#/utils/request';
+import { request } from "#/utils/request";
export namespace SystemUserApi {
/** 鐢ㄦ埛淇℃伅 */
@@ -137,7 +137,7 @@
/** 鑾峰彇鐢ㄦ埛鍒嗛〉鍒楄〃 */
export function getUserPage(params: SystemUserApi.PageParams) {
- return request.get<SystemUserApi.PageResult>('/system/user/page', { params });
+ return request.get<SystemUserApi.PageResult>("/system/user/page", { params });
}
/** 鑾峰彇鐢ㄦ埛璇︽儏 */
@@ -147,12 +147,12 @@
/** 鍒涘缓鐢ㄦ埛 */
export function createUser(data: SystemUserApi.User) {
- return request.post('/system/user/create', data);
+ return request.post("/system/user/create", data);
}
/** 鏇存柊鐢ㄦ埛 */
export function updateUser(data: SystemUserApi.User) {
- return request.put('/system/user/update', data);
+ return request.put("/system/user/update", data);
}
/** 鍒犻櫎鐢ㄦ埛 */
@@ -199,28 +199,28 @@
```vue
<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { SystemUserApi } from '#/api/system/user';
+import type { VxeTableGridOptions } from "#/adapter/vxe-table";
+import type { SystemUserApi } from "#/api/system/user";
-import { useVbenVxeGrid, TableAction, ACTION_ICON } from '#/adapter/vxe-table';
-import { getUserPage } from '#/api/system/user';
+import { useVbenVxeGrid, TableAction, ACTION_ICON } from "#/adapter/vxe-table";
+import { getUserPage } from "#/api/system/user";
// 琛ㄦ牸鍒楅厤缃�
-const columns: VxeTableGridOptions['columns'] = [
- { type: 'checkbox', width: 50 },
- { field: 'username', title: '鐢ㄦ埛鍚�', width: 120 },
- { field: 'nickname', title: '鏄电О', width: 120 },
+const columns: VxeTableGridOptions["columns"] = [
+ { type: "checkbox", width: 50 },
+ { field: "username", title: "鐢ㄦ埛鍚�", width: 120 },
+ { field: "nickname", title: "鏄电О", width: 120 },
{
- field: 'status',
- title: '鐘舵��',
+ field: "status",
+ title: "鐘舵��",
width: 100,
cellRender: {
- name: 'CellDict',
- props: { type: 'common_status' },
+ name: "CellDict",
+ props: { type: "common_status" },
},
},
- { field: 'createTime', title: '鍒涘缓鏃堕棿', width: 180 },
- { field: 'action', title: '鎿嶄綔', width: 200, slots: { default: 'actions' } },
+ { field: "createTime", title: "鍒涘缓鏃堕棿", width: 180 },
+ { field: "action", title: "鎿嶄綔", width: 200, slots: { default: "actions" } },
];
// 琛ㄦ牸瀹炰緥
@@ -228,23 +228,23 @@
formOptions: {
schema: [
{
- fieldName: 'username',
- label: '鐢ㄦ埛鍚�',
- component: 'Input',
+ fieldName: "username",
+ label: "鐢ㄦ埛鍚�",
+ component: "Input",
},
{
- fieldName: 'status',
- label: '鐘舵��',
- component: 'Select',
+ fieldName: "status",
+ label: "鐘舵��",
+ component: "Select",
componentProps: {
- options: getDictOptions('common_status'),
+ options: getDictOptions("common_status"),
},
},
],
},
gridOptions: {
columns,
- height: 'auto',
+ height: "auto",
keepSource: true,
proxyConfig: {
ajax: {
@@ -258,7 +258,7 @@
},
},
rowConfig: {
- keyField: 'id',
+ keyField: "id",
isHover: true,
},
} as VxeTableGridOptions<SystemUserApi.User>,
@@ -302,22 +302,22 @@
#### 琛ㄦ牸鍒楁覆鏌撳櫒
-| 娓叉煋鍣� | 鐢ㄩ�� | 绀轰緥 |
-|--------|------|------|
-| `CellImage` | 鍗曞浘灞曠ず | `cellRender: { name: 'CellImage' }` |
-| `CellImages` | 澶氬浘灞曠ず | `cellRender: { name: 'CellImages' }` |
-| `CellLink` | 閾炬帴鎸夐挳 | `cellRender: { name: 'CellLink', props: { text: '鏌ョ湅' } }` |
-| `CellTag` | 鏍囩灞曠ず | `cellRender: { name: 'CellTag', props: { color: 'blue' } }` |
-| `CellDict` | 瀛楀吀鏍囩 | `cellRender: { name: 'CellDict', props: { type: 'common_status' } }` |
-| `CellSwitch` | 寮�鍏冲垏鎹� | `cellRender: { name: 'CellSwitch', attrs: { beforeChange } }` |
+| 娓叉煋鍣� | 鐢ㄩ�� | 绀轰緥 |
+| --------------- | -------- | -------------------------------------------------------------------- |
+| `CellImage` | 鍗曞浘灞曠ず | `cellRender: { name: 'CellImage' }` |
+| `CellImages` | 澶氬浘灞曠ず | `cellRender: { name: 'CellImages' }` |
+| `CellLink` | 閾炬帴鎸夐挳 | `cellRender: { name: 'CellLink', props: { text: '鏌ョ湅' } }` |
+| `CellTag` | 鏍囩灞曠ず | `cellRender: { name: 'CellTag', props: { color: 'blue' } }` |
+| `CellDict` | 瀛楀吀鏍囩 | `cellRender: { name: 'CellDict', props: { type: 'common_status' } }` |
+| `CellSwitch` | 寮�鍏冲垏鎹� | `cellRender: { name: 'CellSwitch', attrs: { beforeChange } }` |
| `CellOperation` | 鎿嶄綔鎸夐挳 | `cellRender: { name: 'CellOperation', options: ['edit', 'delete'] }` |
### 2.2 琛ㄥ崟寮圭獥 (useVbenModal)
```vue
<script lang="ts" setup>
-import { useVbenModal } from '#/packages/effects/common-ui/src';
-import Form from './modules/form.vue';
+import { useVbenModal } from "#/packages/effects/common-ui/src";
+import Form from "./modules/form.vue";
// 寮圭獥瀹炰緥
const [FormModal, formModalApi] = useVbenModal({
@@ -346,14 +346,14 @@
```vue
<!-- modules/form.vue -->
<script lang="ts" setup>
-import type { SystemUserApi } from '#/api/system/user';
+import type { SystemUserApi } from "#/api/system/user";
-import { computed, ref } from 'vue';
-import { useVbenModal } from '#/packages/effects/common-ui/src';
-import { useVbenForm } from '#/adapter/form';
-import { createUser, updateUser } from '#/api/system/user';
+import { computed, ref } from "vue";
+import { useVbenModal } from "#/packages/effects/common-ui/src";
+import { useVbenForm } from "#/adapter/form";
+import { createUser, updateUser } from "#/api/system/user";
-const emit = defineEmits(['success']);
+const emit = defineEmits(["success"]);
const [Modal, modalApi] = useVbenModal({
async onConfirm() {
@@ -363,7 +363,7 @@
} else {
await createUser(values);
}
- emit('success');
+ emit("success");
modalApi.close();
},
});
@@ -373,27 +373,27 @@
const [Form, formApi] = useVbenForm({
schema: [
{
- fieldName: 'username',
- label: '鐢ㄦ埛鍚�',
- rules: 'required',
- component: 'Input',
+ fieldName: "username",
+ label: "鐢ㄦ埛鍚�",
+ rules: "required",
+ component: "Input",
},
{
- fieldName: 'nickname',
- label: '鏄电О',
- rules: 'required',
- component: 'Input',
+ fieldName: "nickname",
+ label: "鏄电О",
+ rules: "required",
+ component: "Input",
},
{
- fieldName: 'email',
- label: '閭',
- rules: 'email',
- component: 'Input',
+ fieldName: "email",
+ label: "閭",
+ rules: "email",
+ component: "Input",
},
{
- fieldName: 'deptId',
- label: '閮ㄩ棬',
- component: 'TreeSelect',
+ fieldName: "deptId",
+ label: "閮ㄩ棬",
+ component: "TreeSelect",
},
],
});
@@ -422,7 +422,7 @@
```vue
<script lang="ts" setup>
-import DictTag from '#/components/dict-tag/dict-tag.vue';
+import DictTag from "#/components/dict-tag/dict-tag.vue";
</script>
<template>
@@ -436,7 +436,7 @@
```vue
<script lang="ts" setup>
-import DictSelect from '#/components/form-create/components/dict-select.vue';
+import DictSelect from "#/components/form-create/components/dict-select.vue";
</script>
<template>
@@ -462,16 +462,20 @@
#### 瀛楀吀宸ュ叿鍑芥暟
```typescript
-import { getDictOptions, getDictLabel, getDictObj } from '#/packages/effects/hooks/src';
+import {
+ getDictOptions,
+ getDictLabel,
+ getDictObj,
+} from "#/packages/effects/hooks/src";
// 鑾峰彇瀛楀吀閫夐」鍒楄〃锛堢敤浜� Select/Radio 绛夌粍浠讹級
-const options = getDictOptions('common_status', 'number');
+const options = getDictOptions("common_status", "number");
// 鑾峰彇瀛楀吀鏍囩鏂囨湰
-const label = getDictLabel('common_status', 1); // "寮�鍚�"
+const label = getDictLabel("common_status", 1); // "寮�鍚�"
// 鑾峰彇瀛楀吀瀹屾暣瀵硅薄
-const dictObj = getDictObj('common_status', 1);
+const dictObj = getDictObj("common_status", 1);
// { label: '寮�鍚�', value: 1, colorType: 'success', cssClass: '' }
```
@@ -481,7 +485,7 @@
```vue
<script lang="ts" setup>
-import { TableAction, ACTION_ICON } from '#/adapter/vxe-table';
+import { TableAction, ACTION_ICON } from "#/adapter/vxe-table";
</script>
<template>
@@ -523,9 +527,9 @@
```vue
<script lang="ts" setup>
-import ImageUpload from '#/components/upload/image-upload.vue';
+import ImageUpload from "#/components/upload/image-upload.vue";
-const imageUrl = ref('');
+const imageUrl = ref("");
const imageList = ref<string[]>([]);
</script>
@@ -549,7 +553,7 @@
```vue
<script lang="ts" setup>
-import FileUpload from '#/components/upload/file-upload.vue';
+import FileUpload from "#/components/upload/file-upload.vue";
const fileList = ref<string[]>([]);
</script>
@@ -570,26 +574,26 @@
```vue
<script lang="ts" setup>
-import Description from '#/components/description/description.vue';
+import Description from "#/components/description/description.vue";
const data = {
- username: 'admin',
- nickname: '绠$悊鍛�',
- email: 'admin@example.com',
+ username: "admin",
+ nickname: "绠$悊鍛�",
+ email: "admin@example.com",
status: 0,
- createTime: '2024-01-01 12:00:00',
+ createTime: "2024-01-01 12:00:00",
};
const schema = [
- { field: 'username', label: '鐢ㄦ埛鍚�' },
- { field: 'nickname', label: '鏄电О' },
- { field: 'email', label: '閭' },
+ { field: "username", label: "鐢ㄦ埛鍚�" },
+ { field: "nickname", label: "鏄电О" },
+ { field: "email", label: "閭" },
{
- field: 'status',
- label: '鐘舵��',
- render: (value) => h(DictTag, { type: 'common_status', value }),
+ field: "status",
+ label: "鐘舵��",
+ render: (value) => h(DictTag, { type: "common_status", value }),
},
- { field: 'createTime', label: '鍒涘缓鏃堕棿' },
+ { field: "createTime", label: "鍒涘缓鏃堕棿" },
];
</script>
@@ -608,16 +612,16 @@
#### 甯哥敤 Store
-| Store | 鐢ㄩ�� | 瀵煎叆璺緞 |
-|-------|------|----------|
-| `useUserStore` | 鐢ㄦ埛淇℃伅 | `#/packages/stores/src` |
+| Store | 鐢ㄩ�� | 瀵煎叆璺緞 |
+| ---------------- | ---------- | ----------------------- |
+| `useUserStore` | 鐢ㄦ埛淇℃伅 | `#/packages/stores/src` |
| `useAccessStore` | 鏉冮檺/Token | `#/packages/stores/src` |
-| `useDictStore` | 鏁版嵁瀛楀吀 | `#/packages/stores/src` |
+| `useDictStore` | 鏁版嵁瀛楀吀 | `#/packages/stores/src` |
#### 绀轰緥
```typescript
-import { useUserStore, useAccessStore } from '#/packages/stores/src';
+import { useUserStore, useAccessStore } from "#/packages/stores/src";
const userStore = useUserStore();
const accessStore = useAccessStore();
@@ -627,7 +631,7 @@
// 妫�鏌ユ潈闄�
const { hasAccessByCodes } = useAccess();
-const canEdit = hasAccessByCodes(['system:user:update']);
+const canEdit = hasAccessByCodes(["system:user:update"]);
```
---
@@ -638,7 +642,7 @@
```vue
<script lang="ts" setup>
-import { useAccess } from '#/packages/effects/access/src';
+import { useAccess } from "#/packages/effects/access/src";
const { hasAccessByCodes } = useAccess();
</script>
@@ -686,12 +690,12 @@
```vue
<script lang="ts" setup>
-import { $t } from '#/locales';
+import { $t } from "#/locales";
</script>
<template>
- <Button>{{ $t('common.save') }}</Button>
- <span>{{ $t('ui.actionMessage.deleteSuccess', ['鐢ㄦ埛']) }}</span>
+ <Button>{{ $t("common.save") }}</Button>
+ <span>{{ $t("ui.actionMessage.deleteSuccess", ["鐢ㄦ埛"]) }}</span>
</template>
```
@@ -721,7 +725,7 @@
### 6.1 usePagination - 鍒嗛〉
```typescript
-import { usePagination } from '#/packages/effects/hooks/src';
+import { usePagination } from "#/packages/effects/hooks/src";
const { page, pageSize, total, setPage, setTotal } = usePagination();
```
@@ -729,7 +733,7 @@
### 6.2 useTabs - 鏍囩椤垫搷浣�
```typescript
-import { useTabs } from '#/packages/effects/hooks/src';
+import { useTabs } from "#/packages/effects/hooks/src";
const { closeOtherTabs, closeTab, refreshTab } = useTabs();
@@ -743,13 +747,13 @@
### 6.3 useWatermark - 姘村嵃
```typescript
-import { useWatermark } from '#/packages/effects/hooks/src';
+import { useWatermark } from "#/packages/effects/hooks/src";
const { updateWatermark, destroyWatermark } = useWatermark();
// 璁剧疆姘村嵃
await updateWatermark({
- content: '鐢ㄦ埛鍚�',
+ content: "鐢ㄦ埛鍚�",
});
// 閿�姣佹按鍗�
@@ -764,20 +768,20 @@
```typescript
import {
- formatDateTime, // 鏃ユ湡鏍煎紡鍖�
- formatDate, // 鏃ユ湡鏍煎紡鍖栵紙涓嶅惈鏃堕棿锛�
+ formatDateTime, // 鏃ユ湡鏍煎紡鍖�
+ formatDate, // 鏃ユ湡鏍煎紡鍖栵紙涓嶅惈鏃堕棿锛�
downloadFileFromBlobPart, // 鏂囦欢涓嬭浇
- isEmpty, // 鍒ょ┖
- isFunction, // 鍒ゆ柇鍑芥暟
- isString, // 鍒ゆ柇瀛楃涓�
-} from '#/packages/utils/src';
+ isEmpty, // 鍒ょ┖
+ isFunction, // 鍒ゆ柇鍑芥暟
+ isString, // 鍒ゆ柇瀛楃涓�
+} from "#/packages/utils/src";
// 鏃ユ湡鏍煎紡鍖�
-formatDateTime('2024-01-01T12:00:00'); // "2024-01-01 12:00:00"
+formatDateTime("2024-01-01T12:00:00"); // "2024-01-01 12:00:00"
// 鏂囦欢涓嬭浇
downloadFileFromBlobPart({
- fileName: '鐢ㄦ埛鍒楄〃.xlsx',
+ fileName: "鐢ㄦ埛鍒楄〃.xlsx",
source: blobData,
});
@@ -791,10 +795,10 @@
```typescript
import {
- erpNumberFormatter, // 鏁板瓧鏍煎紡鍖�
- fenToYuan, // 鍒嗚浆鍏�
- formatFileSize, // 鏂囦欢澶у皬鏍煎紡鍖�
-} from '#/packages/utils/src';
+ erpNumberFormatter, // 鏁板瓧鏍煎紡鍖�
+ fenToYuan, // 鍒嗚浆鍏�
+ formatFileSize, // 鏂囦欢澶у皬鏍煎紡鍖�
+} from "#/packages/utils/src";
// 淇濈暀涓や綅灏忔暟
erpNumberFormatter(1234.567, 2); // "1,234.57"
@@ -812,28 +816,28 @@
```vue
<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { SystemUserApi } from '#/api/system/user';
+import type { VxeTableGridOptions } from "#/adapter/vxe-table";
+import type { SystemUserApi } from "#/api/system/user";
-import { ref } from 'vue';
+import { ref } from "vue";
-import { confirm, Page, useVbenModal } from '#/packages/effects/common-ui/src';
-import { getDictOptions } from '#/packages/effects/hooks/src';
-import { downloadFileFromBlobPart, isEmpty } from '#/packages/utils/src';
+import { confirm, Page, useVbenModal } from "#/packages/effects/common-ui/src";
+import { getDictOptions } from "#/packages/effects/hooks/src";
+import { downloadFileFromBlobPart, isEmpty } from "#/packages/utils/src";
-import { message } from 'ant-design-vue';
+import { message } from "ant-design-vue";
-import { useVbenVxeGrid, TableAction, ACTION_ICON } from '#/adapter/vxe-table';
+import { useVbenVxeGrid, TableAction, ACTION_ICON } from "#/adapter/vxe-table";
import {
getUserPage,
deleteUser,
createUser,
updateUser,
exportUser,
-} from '#/api/system/user';
-import { $t } from '#/locales';
+} from "#/api/system/user";
+import { $t } from "#/locales";
-import Form from './modules/form.vue';
+import Form from "./modules/form.vue";
// ========== 寮圭獥瀹氫箟 ==========
const [FormModal, formModalApi] = useVbenModal({
@@ -848,37 +852,42 @@
formOptions: {
schema: [
{
- fieldName: 'username',
- label: '鐢ㄦ埛鍚�',
- component: 'Input',
- componentProps: { placeholder: '璇疯緭鍏ョ敤鎴峰悕' },
+ fieldName: "username",
+ label: "鐢ㄦ埛鍚�",
+ component: "Input",
+ componentProps: { placeholder: "璇疯緭鍏ョ敤鎴峰悕" },
},
{
- fieldName: 'status',
- label: '鐘舵��',
- component: 'Select',
+ fieldName: "status",
+ label: "鐘舵��",
+ component: "Select",
componentProps: {
- options: getDictOptions('common_status', 'number'),
- placeholder: '璇烽�夋嫨鐘舵��',
+ options: getDictOptions("common_status", "number"),
+ placeholder: "璇烽�夋嫨鐘舵��",
},
},
],
},
gridOptions: {
columns: [
- { type: 'checkbox', width: 50 },
- { field: 'username', title: '鐢ㄦ埛鍚�', width: 120 },
- { field: 'nickname', title: '鏄电О', width: 120 },
+ { type: "checkbox", width: 50 },
+ { field: "username", title: "鐢ㄦ埛鍚�", width: 120 },
+ { field: "nickname", title: "鏄电О", width: 120 },
{
- field: 'status',
- title: '鐘舵��',
+ field: "status",
+ title: "鐘舵��",
width: 100,
- cellRender: { name: 'CellDict', props: { type: 'common_status' } },
+ cellRender: { name: "CellDict", props: { type: "common_status" } },
},
- { field: 'createTime', title: '鍒涘缓鏃堕棿', width: 180 },
- { field: 'action', title: '鎿嶄綔', width: 180, slots: { default: 'actions' } },
+ { field: "createTime", title: "鍒涘缓鏃堕棿", width: 180 },
+ {
+ field: "action",
+ title: "鎿嶄綔",
+ width: 180,
+ slots: { default: "actions" },
+ },
],
- height: 'auto',
+ height: "auto",
keepSource: true,
proxyConfig: {
ajax: {
@@ -891,7 +900,7 @@
},
},
},
- rowConfig: { keyField: 'id', isHover: true },
+ rowConfig: { keyField: "id", isHover: true },
toolbarConfig: { refresh: true, search: true },
} as VxeTableGridOptions<SystemUserApi.User>,
gridEvents: {
@@ -911,7 +920,7 @@
async function handleExport() {
const data = await exportUser(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '鐢ㄦ埛.xls', source: data });
+ downloadFileFromBlobPart({ fileName: "鐢ㄦ埛.xls", source: data });
}
function handleCreate() {
@@ -924,12 +933,12 @@
async function handleDelete(row: SystemUserApi.User) {
await deleteUser(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.username]));
+ message.success($t("ui.actionMessage.deleteSuccess", [row.username]));
handleRefresh();
}
async function handleDeleteBatch() {
- await confirm($t('ui.actionMessage.deleteBatchConfirm'));
+ await confirm($t("ui.actionMessage.deleteBatchConfirm"));
// ... 鎵归噺鍒犻櫎閫昏緫
}
</script>
--
Gitblit v1.9.3