Commit b1c263d8f86d8f6ae54feb42d8712995bf5e62e2

Authored by gesilong
1 parent d5ea5dd5

commit:针对中建材滕峰公司得改动

... ... @@ -31,6 +31,12 @@ import { getEntitiesId } from '/@/api/dashboard/index';
31 31 import { useRole } from '/@/hooks/business/useRole';
32 32 import { useLocaleStore } from './locale';
33 33
  34 +export const TARGET_TENANT_ID = '0414df80-f01d-11f0-9cb8-e3376d1e7978';
  35 +
  36 +export function isTargetTenantId(tenantId?: string | null) {
  37 + return tenantId === TARGET_TENANT_ID;
  38 +}
  39 +
34 40 interface PlatInfoType {
35 41 id: string;
36 42 creator: string;
... ... @@ -91,6 +97,12 @@ export const useUserStore = defineStore({
91 97 getUserInfo(): UserInfo {
92 98 return this.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {};
93 99 },
  100 + getTenantId(): string | undefined {
  101 + return this.getUserInfo?.tenantId;
  102 + },
  103 + isTargetTenant(): boolean {
  104 + return isTargetTenantId(this.getTenantId);
  105 + },
94 106
95 107 getUserUpdateInfo(): UserUpdateInfo {
96 108 return this.userUpdateInfo || {};
... ...
... ... @@ -51,7 +51,7 @@ import {computed, nextTick, reactive, ref} from "vue";
51 51 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
52 52 import { SchemaFiled} from "../../config/enum";
53 53 import {BasicForm, FileItem, useForm} from "/@/components/Form";
54   -import {formSchema} from "../../config/data";
  54 +import { getFormSchema } from "../../config/data";
55 55 import {useHooks} from "/@/views/report/config/hooks/index.hooks";
56 56 import {getUserListByOrg,ledgerEditDetailPage,saveLedger } from "/@/api/equipment/ledger"
57 57 import {useUserStore} from "/@/store/modules/user";
... ... @@ -98,7 +98,7 @@ const emits = defineEmits(['success', 'register']);
98 98 const [registerForm, { validate, resetFields, setFieldsValue, updateSchema }] = useForm(
99 99 {
100 100 labelWidth: 140,
101   - schemas: formSchema,
  101 + schemas: getFormSchema(userInfo.isTargetTenant),
102 102 showActionButtonGroup: false,
103 103 fieldMapToTime: [[SchemaFiled.DATE_RANGE, [SchemaFiled.START_TS, SchemaFiled.END_TS]]],
104 104 }
... ...
... ... @@ -13,208 +13,223 @@ const statusOptions = [
13 13 { label: t('equipment.ledger.FAULT'), value: 'FAULT' },
14 14 { label: t('equipment.ledger.SCRAP'), value: 'SCRAP' },
15 15 ];
16   -export const formSchema: BFormSchema[] = [
17   - {
18   - field: 'image',
19   - label: t('deviceManagement.product.imageText'),
20   - component: 'ApiUpload',
21   - changeEvent: 'update:fileList',
22   - valueField: 'fileList',
23   - componentProps: ({ formModel }) => {
24   - return {
25   - listType: 'picture-card',
26   - maxFileLimit: 1,
27   - accept: '.png,.jpg,.jpeg,.gif',
28   - api: async (file: File) => {
29   - try {
30   - const formData = new FormData();
31   - formData.set('file', file);
32   - const { fileStaticUri, fileName } = await uploadThumbnail(formData);
33   - return {
34   - uid: fileStaticUri,
35   - name: fileName,
36   - url: fileStaticUri,
37   - };
38   - } catch (error) {
39   - return {};
40   - }
41   - },
42   - onPreview: (fileList) => {
43   - createImgPreview({ imageList: [fileList.url!] });
44   - },
45   - onDelete(url: string) {
46   - formModel.deleteUrl = url!;
47   - },
48   - };
49   - },
50   - },
51   - {
52   - field: 'code',
53   - label: t('equipment.ledger.nameCode'),
54   - component: 'Input',
55   - colProps: { span: 24 },
56   - required: true,
57   - componentProps: {
58   - maxLength: 20,
59   - },
60   - },
61   - {
62   - field: 'name',
63   - label: t('equipment.ledger.deviceName'),
64   - component: 'Input',
65   - colProps: { span: 24 },
66   - required: true,
67   - componentProps: {
68   - maxLength: 20,
69   - },
70   - },
71   - {
72   - field: 'categoryId',
73   - label: t('equipment.category.categoryText'),
74   - colProps: { span: 24 },
75   - component: 'CategoryTreeSelect',
76   - required: true,
77   - },
78   - {
79   - field: 'status',
80   - component: 'Select',
81   - label: t('equipment.ledger.status'),
82   - required: true,
83   - colProps: { span: 24 },
84   - defaultValue: 'NORMAL',
85   - componentProps: {
86   - options: statusOptions,
87   - },
88   - },
89   - {
90   - field: 'isOnline',
91   - component: 'Select',
92   - label: '是否联网',
93   - required: true,
94   - colProps: { span: 24 },
95   - componentProps: {
96   - options: [
97   - {
98   - label: '是',
99   - value: true,
100   - },
101   - {
102   - label: '否',
103   - value: false,
104   - }
105   - ],
106   - },
107   - },
108   - {
109   - field: 'brand',
110   - label: t('equipment.ledger.brandText'),
111   - component: 'Input',
112   - colProps: { span: 24 },
113   - componentProps: {
114   - maxLength: 20,
115   - },
116   - },
117   - {
118   - field: 'modelNum',
119   - label: t('equipment.ledger.modelNumText'),
120   - component: 'Input',
121   - colProps: { span: 24 },
122   - componentProps: {
123   - maxLength: 20,
124   - },
125   - },
126   - {
127   - field: 'specifications',
128   - label: t('equipment.ledger.specificationsText'),
129   - component: 'Input',
130   - colProps: { span: 24 },
131   - componentProps: {
132   - maxLength: 20,
133   - },
134   - },
135   - {
136   - field: 'specifications',
137   - label: t('equipment.ledger.manufacturerText'),
138   - component: 'Input',
139   - colProps: { span: 24 },
140   - componentProps: {
141   - maxLength: 20,
142   - },
143   - },
144   - {
145   - field: 'buyDate',
146   - label: t('equipment.ledger.buyDate'),
147   - component: 'DatePicker',
148   - colProps: { span: 24 },
149   - componentProps: {
150   - format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
151   - showTime: true, // 显示时间选择器
152   - },
153   - },
154   -{
155   - field: 'price',
156   - label: t('equipment.ledger.priceText'),
157   - component: 'InputNumber',
158   - colProps: { span: 24 },
159   - componentProps: {
160   - },
161   - },
162   - {
163   - field: 'productDate',
164   - label: t('equipment.ledger.productDate'),
165   - component: 'DatePicker',
166   - colProps: { span: 24 },
167   - componentProps: {
168   - format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
169   - showTime: true, // 显示时间选择器
170   - },
171   - },
172   - {
173   - field: 'receiveDate',
174   - label: t('equipment.ledger.receiveDate'),
175   - component: 'DatePicker',
176   - colProps: { span: 24 },
177   - componentProps: {
178   - format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
179   - showTime: true, // 显示时间选择器
180   - },
181   - },
182   - {
183   - field: 'registeDate',
184   - label: t('equipment.ledger.registeDate'),
185   - component: 'DatePicker',
186   - colProps: { span: 24 },
187   - componentProps: {
188   - format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
189   - showTime: true, // 显示时间选择器
190   - },
191   - },
192   - {
193   - field: 'supplierId',
194   - component: 'ApiSelect',
195   - label: '供应商',
196   - colProps: { span: 24 },
197   - required: true,
198   - componentProps: ({ }) => {
199   - return {
200   - api: supplierListPull,
201   - params: {
  16 +export function getFormSchema(isTargetTenant: boolean): BFormSchema[] {
  17 + const codeLabel = isTargetTenant ? '设备位号' : t('equipment.ledger.nameCode');
202 18
203   - },
204   - labelField: 'name',
205   - valueField: 'id',
206   - getPopupContainer: () => document.body,
207   - };
208   - },
209   - },
210   - {
211   - field: 'description',
212   - label: t('equipment.ledger.description'),
213   - component: 'InputTextArea',
214   - colProps: { span: 24 },
215   - componentProps: {
216   - maxLength: 200,
217   - },
218   - },
  19 + const schema: BFormSchema[] = [
  20 + {
  21 + field: 'image',
  22 + label: t('deviceManagement.product.imageText'),
  23 + component: 'ApiUpload',
  24 + changeEvent: 'update:fileList',
  25 + valueField: 'fileList',
  26 + componentProps: ({ formModel }) => {
  27 + return {
  28 + listType: 'picture-card',
  29 + maxFileLimit: 1,
  30 + accept: '.png,.jpg,.jpeg,.gif',
  31 + api: async (file: File) => {
  32 + try {
  33 + const formData = new FormData();
  34 + formData.set('file', file);
  35 + const { fileStaticUri, fileName } = await uploadThumbnail(formData);
  36 + return {
  37 + uid: fileStaticUri,
  38 + name: fileName,
  39 + url: fileStaticUri,
  40 + };
  41 + } catch (error) {
  42 + return {};
  43 + }
  44 + },
  45 + onPreview: (fileList) => {
  46 + createImgPreview({ imageList: [fileList.url!] });
  47 + },
  48 + onDelete(url: string) {
  49 + formModel.deleteUrl = url!;
  50 + },
  51 + };
  52 + },
  53 + },
  54 + {
  55 + field: 'code',
  56 + label: codeLabel,
  57 + component: 'Input',
  58 + colProps: { span: 24 },
  59 + required: true,
  60 + componentProps: {
  61 + maxLength: 20,
  62 + },
  63 + },
  64 + {
  65 + field: 'name',
  66 + label: t('equipment.ledger.deviceName'),
  67 + component: 'Input',
  68 + colProps: { span: 24 },
  69 + required: true,
  70 + componentProps: {
  71 + maxLength: 20,
  72 + },
  73 + },
  74 + {
  75 + field: 'categoryId',
  76 + label: t('equipment.category.categoryText'),
  77 + colProps: { span: 24 },
  78 + component: 'CategoryTreeSelect',
  79 + required: true,
  80 + },
  81 + {
  82 + field: 'status',
  83 + component: 'Select',
  84 + label: t('equipment.ledger.status'),
  85 + required: true,
  86 + colProps: { span: 24 },
  87 + defaultValue: 'NORMAL',
  88 + componentProps: {
  89 + options: statusOptions,
  90 + },
  91 + },
  92 + {
  93 + field: 'isOnline',
  94 + component: 'Select',
  95 + label: '是否联网',
  96 + required: true,
  97 + colProps: { span: 24 },
  98 + componentProps: {
  99 + options: [
  100 + {
  101 + label: '是',
  102 + value: true,
  103 + },
  104 + {
  105 + label: '否',
  106 + value: false,
  107 + },
  108 + ],
  109 + },
  110 + },
  111 + {
  112 + field: 'brand',
  113 + label: t('equipment.ledger.brandText'),
  114 + component: 'Input',
  115 + colProps: { span: 24 },
  116 + componentProps: {
  117 + maxLength: 20,
  118 + },
  119 + },
  120 + {
  121 + field: 'modelNum',
  122 + label: t('equipment.ledger.modelNumText'),
  123 + component: 'Input',
  124 + colProps: { span: 24 },
  125 + componentProps: {
  126 + maxLength: 20,
  127 + },
  128 + },
  129 + {
  130 + field: 'specifications',
  131 + label: t('equipment.ledger.specificationsText'),
  132 + component: 'Input',
  133 + colProps: { span: 24 },
  134 + componentProps: {
  135 + maxLength: 20,
  136 + },
  137 + },
  138 + {
  139 + field: 'specifications',
  140 + label: t('equipment.ledger.manufacturerText'),
  141 + component: 'Input',
  142 + colProps: { span: 24 },
  143 + componentProps: {
  144 + maxLength: 20,
  145 + },
  146 + },
  147 + {
  148 + field: 'buyDate',
  149 + label: t('equipment.ledger.buyDate'),
  150 + component: 'DatePicker',
  151 + colProps: { span: 24 },
  152 + componentProps: {
  153 + format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
  154 + showTime: true, // 显示时间选择器
  155 + },
  156 + },
  157 + {
  158 + field: 'price',
  159 + label: t('equipment.ledger.priceText'),
  160 + component: 'InputNumber',
  161 + colProps: { span: 24 },
  162 + componentProps: {},
  163 + },
  164 + {
  165 + field: 'productDate',
  166 + label: t('equipment.ledger.productDate'),
  167 + component: 'DatePicker',
  168 + colProps: { span: 24 },
  169 + componentProps: {
  170 + format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
  171 + showTime: true, // 显示时间选择器
  172 + },
  173 + },
  174 + {
  175 + field: 'receiveDate',
  176 + label: t('equipment.ledger.receiveDate'),
  177 + component: 'DatePicker',
  178 + colProps: { span: 24 },
  179 + componentProps: {
  180 + format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
  181 + showTime: true, // 显示时间选择器
  182 + },
  183 + },
  184 + {
  185 + field: 'registeDate',
  186 + label: t('equipment.ledger.registeDate'),
  187 + component: 'DatePicker',
  188 + colProps: { span: 24 },
  189 + componentProps: {
  190 + format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
  191 + showTime: true, // 显示时间选择器
  192 + },
  193 + },
  194 + {
  195 + field: 'supplierId',
  196 + component: 'ApiSelect',
  197 + label: '供应商',
  198 + colProps: { span: 24 },
  199 + required: true,
  200 + componentProps: ({}) => {
  201 + return {
  202 + api: supplierListPull,
  203 + params: {},
  204 + labelField: 'name',
  205 + valueField: 'id',
  206 + getPopupContainer: () => document.body,
  207 + };
  208 + },
  209 + },
  210 + {
  211 + field: 'description',
  212 + label: t('equipment.ledger.description'),
  213 + component: 'InputTextArea',
  214 + colProps: { span: 24 },
  215 + componentProps: {
  216 + maxLength: 200,
  217 + },
  218 + },
  219 + ];
219 220
220   -];
  221 + if (isTargetTenant) {
  222 + schema.splice(schema.length - 1, 0, {
  223 + field: 'techFeature',
  224 + label: '主要技术特征',
  225 + component: 'InputTextArea',
  226 + colProps: { span: 24 },
  227 + componentProps: {
  228 + rows: 4,
  229 + maxLength: 2000,
  230 + },
  231 + });
  232 + }
  233 +
  234 + return schema;
  235 +}
... ...
... ... @@ -66,8 +66,10 @@ export enum DeviceListAuthEnum {
66 66 UPDATE_PRODUCT = 'api:yt:device:update:product',
67 67 }
68 68
69   -// 表格列数据
70   -export const columns: BasicColumn[] = [
  69 +export function getColumns(isTargetTenant: boolean): BasicColumn[] {
  70 + const codeTitle = isTargetTenant ? '设备位号' : t('business.codeText');
  71 +
  72 + return [
71 73 {
72 74 title: t('repair.order.situationImg'),
73 75 dataIndex: 'deviceImg',
... ... @@ -82,7 +84,7 @@ export const columns: BasicColumn[] = [
82 84 slots: { customRender: 'status' },
83 85 },
84 86 {
85   - title: t('business.codeText'),
  87 + title: codeTitle,
86 88 dataIndex: 'code',
87 89 width: 100,
88 90 },
... ... @@ -157,29 +159,47 @@ export const columns: BasicColumn[] = [
157 159 dataIndex: 'brand',
158 160 width: 120,
159 161 },
160   -];
  162 + ];
  163 +}
161 164
162   -// 查询字段
163   -export const searchFormSchema: FormSchema[] = [
164   - {
165   - field: 'code',
166   - label: t('equipment.ledger.deviceCode'),
167   - component: 'Input',
168   - colProps: { span: 6 },
169   - componentProps: {
170   - maxLength: 255,
  165 +export function getSearchFormSchema(isTargetTenant: boolean): FormSchema[] {
  166 + const codeLabel = isTargetTenant ? '设备位号' : t('equipment.ledger.deviceCode');
  167 +
  168 + const schema: FormSchema[] = [
  169 + {
  170 + field: 'code',
  171 + label: codeLabel,
  172 + component: 'Input',
  173 + colProps: { span: 6 },
  174 + componentProps: {
  175 + maxLength: 255,
  176 + },
171 177 },
172   - },
173   - {
174   - field: 'status',
175   - label: t('business.deviceStatusText'),
176   - component: 'Select',
177   - componentProps: {
178   - options: Object.values(SbStatusEnum).map((value) => ({
179   - label: t(`enum.sbStatus.${value}`),
180   - value,
181   - })),
  178 + {
  179 + field: 'status',
  180 + label: t('business.deviceStatusText'),
  181 + component: 'Select',
  182 + componentProps: {
  183 + options: Object.values(SbStatusEnum).map((value) => ({
  184 + label: t(`enum.sbStatus.${value}`),
  185 + value,
  186 + })),
  187 + },
  188 + colProps: { span: 6 },
182 189 },
183   - colProps: { span: 6 },
  190 + ];
  191 +
  192 + if (isTargetTenant) {
  193 + schema.splice(1, 0, {
  194 + field: 'name',
  195 + label: t('equipment.ledger.deviceName'),
  196 + component: 'Input',
  197 + colProps: { span: 6 },
  198 + componentProps: {
  199 + maxLength: 255,
  200 + },
  201 + });
184 202 }
185   -];
  203 +
  204 + return schema;
  205 +}
... ...
... ... @@ -82,8 +82,8 @@ import {BasicTable, TableAction, TableImg, useTable} from "/@/components/Table";
82 82 import {OrganizationIdTree, useResetOrganizationTree} from "/@/views/common/organizationIdTree";
83 83 import { getLedgerList, deleteLedger } from "/@/api/equipment/ledger"
84 84 import {
85   - columns,
86   - searchFormSchema
  85 + getColumns,
  86 + getSearchFormSchema
87 87 } from "/@/views/equipment/ledger/config/ledger.data";
88 88 import { SbStatusEnum } from '/@/enums/deviceEnum';
89 89
... ... @@ -94,6 +94,7 @@ import {Authority} from "/@/components/Authority";
94 94 import {getAuthCache} from "/@/utils/auth";
95 95 import {USER_INFO_KEY} from "/@/enums/cacheEnum";
96 96 import {useMessage} from "/@/hooks/web/useMessage";
  97 +import { useUserStore } from '/@/store/modules/user';
97 98
98 99 import {useDrawer} from "/@/components/Drawer";
99 100
... ... @@ -102,6 +103,9 @@ const [registerDrawer, { openDrawer }] = useDrawer();
102 103 const { t } = useI18n();
103 104 const userInfo: any = getAuthCache(USER_INFO_KEY);
104 105 const role: string = userInfo.roles[0];
  106 +const userStore = useUserStore();
  107 +const columns = getColumns(userStore.isTargetTenant);
  108 +const searchFormSchema = getSearchFormSchema(userStore.isTargetTenant);
105 109
106 110 const { createMessage } = useMessage();
107 111
... ...
... ... @@ -70,7 +70,11 @@
70 70 </a-form-item>
71 71 </a-col>
72 72 </a-row>
73   - <a-form-item label="巡检明细" name="tkCheckDetailsDTOList">
  73 + <a-form-item label="巡检明细"
  74 + name="tkCheckDetailsDTOList"
  75 + :label-col="{ span: 4 }"
  76 + :wrapper-col="{ span: 19 }"
  77 + >
74 78 <div style="text-align: end">
75 79 <a-button class="editable-add-btn" type="primary" @click="handleAdd" style="margin-bottom: 8px" :disabled="isViewMode">
76 80 <template #icon>
... ... @@ -86,13 +90,23 @@
86 90 </template>
87 91 <template #checkDeviceId="{ text, record, index }">
88 92 <div>
89   - <a-select
90   - v-model:value="record.checkDeviceId"
91   - :options="Options"
92   - :disabled="isViewMode"
93   - :field-names="{ label: 'name', value: 'id' }"
94   - placeholder="请选择"
95   - />
  93 + <template v-if="userStore.isTargetTenant">
  94 + <div style="display: flex; gap: 8px">
  95 + <a-input :value="getDeviceLabel(record)" :disabled="true" placeholder="请选择" />
  96 + <a-button type="primary" @click="goChooseDevice(record)" :disabled="isViewMode">
  97 + 选设备
  98 + </a-button>
  99 + </div>
  100 + </template>
  101 + <template v-else>
  102 + <a-select
  103 + v-model:value="record.checkDeviceId"
  104 + :options="Options"
  105 + :disabled="isViewMode"
  106 + :field-names="{ label: 'name', value: 'id' }"
  107 + placeholder="请选择"
  108 + />
  109 + </template>
96 110 </div>
97 111 </template>
98 112 <template #checkPlanId="{ text, record, index }">
... ... @@ -121,14 +135,45 @@
121 135 </a-form-item>
122 136 </a-form>
123 137 </a-modal>
  138 + <a-modal
  139 + v-model:visible="deviceVisible"
  140 + title="选择设备"
  141 + width="70vw"
  142 + height="60vh"
  143 + @ok="handleDeviceOk"
  144 + @cancel="handleDeviceCancel"
  145 + >
  146 + <div style="padding: 20px">
  147 + <div style="display: flex; gap: 12px; margin-bottom: 12px">
  148 + <a-input
  149 + v-model:value="deviceSearchInfo.code"
  150 + placeholder="设备位号"
  151 + allowClear
  152 + style="width: 240px"
  153 + />
  154 + <a-input
  155 + v-model:value="deviceSearchInfo.name"
  156 + placeholder="设备名称"
  157 + allowClear
  158 + style="width: 240px"
  159 + />
  160 + <a-button type="primary" @click="handleDeviceSearch">搜索</a-button>
  161 + <a-button @click="handleDeviceReset">重置</a-button>
  162 + </div>
  163 + <BasicTable @register="registerDeviceTable" />
  164 + </div>
  165 + </a-modal>
124 166 </template>
125 167 <script setup lang="ts">
126 168 // 定义 props
127   -import {onMounted, ref, watch} from "vue";
  169 +import {onMounted, ref, watch, reactive} from "vue";
128 170 import {getLedgerList} from "/@/api/equipment/ledger";
129 171 import {getPlanList} from "/@/api/equipment/chenkPlan";
  172 +import { useUserStore } from '/@/store/modules/user';
  173 +import { BasicTable, useTable } from '/@/components/Table';
130 174 const Options = ref([]);
131 175 const planOptions = ref([]);
  176 +const userStore = useUserStore();
132 177 const props = defineProps({
133 178 initialData: {
134 179 type: Object,
... ... @@ -209,6 +254,33 @@ const modalTitle = ref(props.modalTitle);
209 254 const form = ref({ ...props.initialData.form });
210 255 const tableData = ref([...props.initialData.tableData]);
211 256 const emit = defineEmits(['update:visible', 'submit']);
  257 +const deviceVisible = ref(false);
  258 +const deviceSearchInfo = reactive<Recordable>({ code: '', name: '' });
  259 +const selectedDevice = ref<any>(null);
  260 +const activeDeviceRecord = ref<any>(null);
  261 +
  262 +const [registerDeviceTable, { reload: reloadDeviceTable }] = useTable({
  263 + api: getLedgerList,
  264 + columns: [
  265 + { title: '设备位号', dataIndex: 'code', width: 160 },
  266 + { title: '设备名称', dataIndex: 'name', width: 240 },
  267 + ],
  268 + searchInfo: deviceSearchInfo,
  269 + useSearchForm: false,
  270 + showTableSetting: false,
  271 + bordered: true,
  272 + showIndexColumn: false,
  273 + clickToRowSelect: false,
  274 + rowKey: 'id',
  275 + pagination: { pageSize: 10 },
  276 + rowSelection: {
  277 + type: 'radio',
  278 + onSelect: (record) => {
  279 + selectedDevice.value = record;
  280 + },
  281 + onSelectAll: () => {},
  282 + },
  283 +});
212 284 // 监听 visible 的变化
213 285 watch(
214 286 () => props.visible,
... ... @@ -251,22 +323,51 @@ const fetchAgeOptions = async () => {
251 323 try {
252 324 const response = await getLedgerList({ page: 1, pageSize: 999 }); // 调用接口
253 325 const response1 = await getPlanList({ page: 1, pageSize: 999, type: 'INSPECTION' }); // 调用接口
254   - Options.value = response.items?.map((item: any) => {
255   - return {
256   - value: item?.id,
257   - label: item?.name
258   - }
259   - })
260   - planOptions.value = response1.items?.map((item: any) => {
261   - return {
262   - value: item?.id,
263   - label: item?.name
264   - }
265   - });
  326 + Options.value = response.items || [];
  327 + planOptions.value = response1.items || [];
266 328 } catch (error) {
267 329 console.error('失败:', error);
268 330 }
269 331 };
  332 +
  333 +const getDeviceLabel = (record: any) => {
  334 + const code = record?.deviceCode;
  335 + const name = record?.deviceName;
  336 + if (code && name) return `${code} / ${name}`;
  337 + return name || code || '';
  338 +};
  339 +
  340 +const goChooseDevice = (record: any) => {
  341 + activeDeviceRecord.value = record;
  342 + selectedDevice.value = null;
  343 + deviceVisible.value = true;
  344 + reloadDeviceTable();
  345 +};
  346 +
  347 +const handleDeviceSearch = () => {
  348 + reloadDeviceTable();
  349 +};
  350 +
  351 +const handleDeviceReset = () => {
  352 + deviceSearchInfo.code = '';
  353 + deviceSearchInfo.name = '';
  354 + reloadDeviceTable();
  355 +};
  356 +
  357 +const handleDeviceOk = () => {
  358 + if (!selectedDevice.value?.id || !activeDeviceRecord.value) {
  359 + deviceVisible.value = false;
  360 + return;
  361 + }
  362 + activeDeviceRecord.value.checkDeviceId = selectedDevice.value.id;
  363 + activeDeviceRecord.value.deviceCode = selectedDevice.value.code;
  364 + activeDeviceRecord.value.deviceName = selectedDevice.value.name;
  365 + deviceVisible.value = false;
  366 +};
  367 +
  368 +const handleDeviceCancel = () => {
  369 + deviceVisible.value = false;
  370 +};
270 371 const handleAdd = () => {
271 372 tableData.value.push({
272 373 code: '',
... ...
... ... @@ -70,11 +70,25 @@
70 70 </a-col>
71 71
72 72 </a-row>
73   - <a-form-item label="巡检明细" name="tkInspectionDetailsDTOList">
  73 + <a-form-item label="巡检明细"
  74 + name="tkInspectionDetailsDTOList"
  75 + :label-col="{ span: 4 }"
  76 + :wrapper-col="{ span: 19 }"
  77 + >
74 78 <a-table bordered :data-source="tableData" :columns="columns">
75   - <template #tkDeviceAccountDTO="{record}">
  79 + <template #tkDeviceAccountDTO="{ record }">
76 80 <div>
77   - {{record?.tkDeviceAccountDTO?.name}}
  81 + <template v-if="userInfo.isTargetTenant">
  82 + <div style="display: flex; gap: 8px">
  83 + <a-input :value="getDeviceLabel(record)" :disabled="true" placeholder="请选择" />
  84 + <a-button type="primary" @click="goChooseDevice(record)" :disabled="isViewMode">
  85 + 选设备
  86 + </a-button>
  87 + </div>
  88 + </template>
  89 + <template v-else>
  90 + {{ record?.tkDeviceAccountDTO?.name }}
  91 + </template>
78 92 </div>
79 93 </template>
80 94 <template #recordResult="{ record }">
... ... @@ -115,6 +129,34 @@
115 129 </div>
116 130 </a-modal>
117 131 </a-modal>
  132 + <a-modal
  133 + v-model:visible="deviceVisible"
  134 + title="选择设备"
  135 + width="70vw"
  136 + height="60vh"
  137 + @ok="handleDeviceOk"
  138 + @cancel="handleDeviceCancel"
  139 + >
  140 + <div style="padding: 20px">
  141 + <div style="display: flex; gap: 12px; margin-bottom: 12px">
  142 + <a-input
  143 + v-model:value="deviceSearchInfo.code"
  144 + placeholder="设备位号"
  145 + allowClear
  146 + style="width: 240px"
  147 + />
  148 + <a-input
  149 + v-model:value="deviceSearchInfo.name"
  150 + placeholder="设备名称"
  151 + allowClear
  152 + style="width: 240px"
  153 + />
  154 + <a-button type="primary" @click="handleDeviceSearch">搜索</a-button>
  155 + <a-button @click="handleDeviceReset">重置</a-button>
  156 + </div>
  157 + <BasicTable @register="registerDeviceTable" />
  158 + </div>
  159 + </a-modal>
118 160 </template>
119 161 <script setup lang="ts">
120 162 import {computed, onMounted, reactive, ref, unref, watch} from "vue";
... ... @@ -126,6 +168,8 @@ import {useUserStore} from "/@/store/modules/user";
126 168 import {useI18n} from "/@/hooks/web/useI18n";
127 169 import {useMessage} from "/@/hooks/web/useMessage";
128 170 import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree';
  171 +import { BasicTable, useTable } from '/@/components/Table';
  172 +import { getLedgerList } from '/@/api/equipment/ledger';
129 173 interface Value {
130 174 value?: string;
131 175 label?: string;
... ... @@ -202,6 +246,10 @@ const emit = defineEmits(['update:visible', 'submit']);
202 246 const planOptions = ref([]);
203 247 const Options = ref([]);
204 248 const userInfo = useUserStore();
  249 +const deviceVisible = ref(false);
  250 +const deviceSearchInfo = reactive<Recordable>({ code: '', name: '' });
  251 +const selectedDevice = ref<any>(null);
  252 +const activeDeviceRecord = ref<any>(null);
205 253 const timespan = ref(Date.now());
206 254 const orgList = ref<Recordable[]>([]);
207 255 const { t } = useI18n();
... ... @@ -220,6 +268,29 @@ const radioStyle = reactive({
220 268 lineHeight: '30px',
221 269 });
222 270
  271 +const [registerDeviceTable, { reload: reloadDeviceTable }] = useTable({
  272 + api: getLedgerList,
  273 + columns: [
  274 + { title: '设备位号', dataIndex: 'code', width: 160 },
  275 + { title: '设备名称', dataIndex: 'name', width: 240 },
  276 + ],
  277 + searchInfo: deviceSearchInfo,
  278 + useSearchForm: false,
  279 + showTableSetting: false,
  280 + bordered: true,
  281 + showIndexColumn: false,
  282 + clickToRowSelect: false,
  283 + rowKey: 'id',
  284 + pagination: { pageSize: 10 },
  285 + rowSelection: {
  286 + type: 'radio',
  287 + onSelect: (record) => {
  288 + selectedDevice.value = record;
  289 + },
  290 + onSelectAll: () => {},
  291 + },
  292 +});
  293 +
223 294 // 监听 visible 的变化
224 295 watch(
225 296 () => props.visible,
... ... @@ -320,11 +391,58 @@ const handleChange = async (value: Value) => {
320 391 checkDeviceId: item?.checkDeviceId || '',
321 392 recordResult: true,
322 393 planDetails: item?.planDetails || '',
323   - tkDeviceAccountDTO: item?.tkDeviceAccountDTO
  394 + tkDeviceAccountDTO: item?.tkDeviceAccountDTO,
  395 + deviceCode: item?.tkDeviceAccountDTO?.code || item?.deviceCode,
  396 + deviceName: item?.tkDeviceAccountDTO?.name || item?.deviceName,
324 397 }
325 398 }) || []
326 399 };
327 400
  401 +const getDeviceLabel = (record: any) => {
  402 + const code = record?.deviceCode;
  403 + const name = record?.deviceName;
  404 + if (code && name) return `${code} / ${name}`;
  405 + return name || code || '';
  406 +};
  407 +
  408 +const goChooseDevice = (record: any) => {
  409 + activeDeviceRecord.value = record;
  410 + selectedDevice.value = null;
  411 + deviceVisible.value = true;
  412 + reloadDeviceTable();
  413 +};
  414 +
  415 +const handleDeviceSearch = () => {
  416 + reloadDeviceTable();
  417 +};
  418 +
  419 +const handleDeviceReset = () => {
  420 + deviceSearchInfo.code = '';
  421 + deviceSearchInfo.name = '';
  422 + reloadDeviceTable();
  423 +};
  424 +
  425 +const handleDeviceOk = () => {
  426 + if (!selectedDevice.value?.id || !activeDeviceRecord.value) {
  427 + deviceVisible.value = false;
  428 + return;
  429 + }
  430 + activeDeviceRecord.value.checkDeviceId = selectedDevice.value.id;
  431 + activeDeviceRecord.value.deviceCode = selectedDevice.value.code;
  432 + activeDeviceRecord.value.deviceName = selectedDevice.value.name;
  433 + activeDeviceRecord.value.tkDeviceAccountDTO = {
  434 + ...(activeDeviceRecord.value.tkDeviceAccountDTO || {}),
  435 + id: selectedDevice.value.id,
  436 + code: selectedDevice.value.code,
  437 + name: selectedDevice.value.name,
  438 + };
  439 + deviceVisible.value = false;
  440 +};
  441 +
  442 +const handleDeviceCancel = () => {
  443 + deviceVisible.value = false;
  444 +};
  445 +
328 446 const handleOk = () => {
329 447 if (isViewMode.value) {
330 448 visible.value = false;
... ...
... ... @@ -43,7 +43,12 @@
43 43 </a-form-item>
44 44 </a-col>
45 45 </a-row>
46   - <a-form-item label="保养明细" name="preserveDetailList">
  46 + <a-form-item
  47 + label="保养明细"
  48 + name="preserveDetailList"
  49 + :label-col="{ span: 4 }"
  50 + :wrapper-col="{ span: 19 }"
  51 + >
47 52 <div style="text-align: end">
48 53 <a-button class="editable-add-btn" type="primary" @click="handleAdd" style="margin-bottom: 8px" :disabled="isViewMode">
49 54 <template #icon>
... ... @@ -60,13 +65,23 @@
60 65 </template>
61 66 <template #deviceId="{ text, record, index }">
62 67 <div>
63   - <a-select
64   - v-model:value="record.deviceId"
65   - :options="Options"
66   - :disabled="isViewMode"
67   - :field-names="{ label: 'name', value: 'id' }"
68   - placeholder="请选择"
69   - />
  68 + <template v-if="userStore.isTargetTenant">
  69 + <div style="display: flex; gap: 8px">
  70 + <a-input :value="getDeviceLabel(record)" :disabled="true" placeholder="请选择" />
  71 + <a-button type="primary" @click="goChooseDevice(record)" :disabled="isViewMode">
  72 + 选设备
  73 + </a-button>
  74 + </div>
  75 + </template>
  76 + <template v-else>
  77 + <a-select
  78 + v-model:value="record.deviceId"
  79 + :options="Options"
  80 + :disabled="isViewMode"
  81 + :field-names="{ label: 'name', value: 'id' }"
  82 + placeholder="请选择"
  83 + />
  84 + </template>
70 85 </div>
71 86 </template>
72 87 <template #checkPlanId="{ record }">
... ... @@ -77,6 +92,7 @@
77 92 :disabled="isViewMode"
78 93 :fieldNames="{ label: 'name', value: 'id' }"
79 94 placeholder="请选择"
  95 + @change="(value) => handleCheckPlanChange(value, record)"
80 96 />
81 97 </div>
82 98 </template>
... ... @@ -94,17 +110,48 @@
94 110 </a-form-item>
95 111 </a-form>
96 112 </a-modal>
  113 + <a-modal
  114 + v-model:visible="deviceVisible"
  115 + title="选择设备"
  116 + width="70vw"
  117 + height="60vh"
  118 + @ok="handleDeviceOk"
  119 + @cancel="handleDeviceCancel"
  120 + >
  121 + <div style="padding: 20px">
  122 + <div style="display: flex; gap: 12px; margin-bottom: 12px">
  123 + <a-input
  124 + v-model:value="deviceSearchInfo.code"
  125 + placeholder="设备位号"
  126 + allowClear
  127 + style="width: 240px"
  128 + />
  129 + <a-input
  130 + v-model:value="deviceSearchInfo.name"
  131 + placeholder="设备名称"
  132 + allowClear
  133 + style="width: 240px"
  134 + />
  135 + <a-button type="primary" @click="handleDeviceSearch">搜索</a-button>
  136 + <a-button @click="handleDeviceReset">重置</a-button>
  137 + </div>
  138 + <BasicTable @register="registerDeviceTable" />
  139 + </div>
  140 + </a-modal>
97 141 </template>
98 142
99 143 <script setup lang="ts">
100   -import { ref, onMounted, watch } from 'vue';
  144 +import { ref, onMounted, watch, reactive } from 'vue';
101 145 import { getLedgerList } from "/@/api/equipment/ledger";
102 146 import { getPlanList } from "/@/api/equipment/chenkPlan";
103 147 import { useI18n } from "/@/hooks/web/useI18n";
  148 +import { useUserStore } from '/@/store/modules/user';
  149 +import { BasicTable, useTable } from '/@/components/Table';
104 150
105 151 const Options = ref([]);
106 152 const planOptions = ref([]);
107 153 const { t } = useI18n();
  154 +const userStore = useUserStore();
108 155 // 定义 props
109 156 const props = defineProps({
110 157 initialData: {
... ... @@ -169,27 +216,89 @@ onMounted(() => {
169 216 fetchAgeOptions();
170 217 });
171 218
  219 +const deviceVisible = ref(false);
  220 +const deviceSearchInfo = reactive<Recordable>({ code: '', name: '' });
  221 +const selectedDevice = ref<any>(null);
  222 +const activeDeviceRecord = ref<any>(null);
  223 +
  224 +const [registerDeviceTable, { reload: reloadDeviceTable }] = useTable({
  225 + api: getLedgerList,
  226 + columns: [
  227 + { title: '设备位号', dataIndex: 'code', width: 160 },
  228 + { title: '设备名称', dataIndex: 'name', width: 240 },
  229 + ],
  230 + searchInfo: deviceSearchInfo,
  231 + useSearchForm: false,
  232 + showTableSetting: false,
  233 + bordered: true,
  234 + showIndexColumn: false,
  235 + clickToRowSelect: false,
  236 + rowKey: 'id',
  237 + pagination: { pageSize: 10 },
  238 + rowSelection: {
  239 + type: 'radio',
  240 + onSelect: (record) => {
  241 + selectedDevice.value = record;
  242 + },
  243 + onSelectAll: () => {},
  244 + },
  245 +});
  246 +
172 247 const fetchAgeOptions = async () => {
173 248 try {
174 249 const response = await getLedgerList({ page: 1, pageSize: 999 }); // 调用接口
175 250 const response1 = await getPlanList({ page: 1, pageSize: 999, type: 'MAINTENANCE' }); // 调用接口
176   - Options.value = response.items?.map((item: any) => {
177   - return {
178   - value: item?.id,
179   - label: item?.name
180   - }
181   - })
182   - planOptions.value = response1.items?.map((item: any) => {
183   - return {
184   - value: item?.id,
185   - label: item?.name
186   - }
187   - });
  251 + Options.value = response.items || [];
  252 + planOptions.value = response1.items || [];
188 253 } catch (error) {
189 254 console.error('失败:', error);
190 255 }
191 256 };
192 257
  258 +const handleCheckPlanChange = (checkPlanId: any, record: any) => {
  259 + const selected = planOptions.value?.find((item: any) => item?.id === checkPlanId);
  260 + record.preserveDetail = selected?.planDetails || '';
  261 +};
  262 +
  263 +const getDeviceLabel = (record: any) => {
  264 + const code = record?.deviceCode;
  265 + const name = record?.deviceName;
  266 + if (code && name) return `${code} / ${name}`;
  267 + return name || code || '';
  268 +};
  269 +
  270 +const goChooseDevice = (record: any) => {
  271 + activeDeviceRecord.value = record;
  272 + selectedDevice.value = null;
  273 + deviceVisible.value = true;
  274 + reloadDeviceTable();
  275 +};
  276 +
  277 +const handleDeviceSearch = () => {
  278 + reloadDeviceTable();
  279 +};
  280 +
  281 +const handleDeviceReset = () => {
  282 + deviceSearchInfo.code = '';
  283 + deviceSearchInfo.name = '';
  284 + reloadDeviceTable();
  285 +};
  286 +
  287 +const handleDeviceOk = () => {
  288 + if (!selectedDevice.value?.id || !activeDeviceRecord.value) {
  289 + deviceVisible.value = false;
  290 + return;
  291 + }
  292 + activeDeviceRecord.value.deviceId = selectedDevice.value.id;
  293 + activeDeviceRecord.value.deviceCode = selectedDevice.value.code;
  294 + activeDeviceRecord.value.deviceName = selectedDevice.value.name;
  295 + deviceVisible.value = false;
  296 +};
  297 +
  298 +const handleDeviceCancel = () => {
  299 + deviceVisible.value = false;
  300 +};
  301 +
193 302 // 监听 visible 的变化
194 303 watch(
195 304 () => props.visible,
... ...
... ... @@ -70,11 +70,25 @@
70 70 </a-form-item>
71 71 </a-col>
72 72 </a-row>
73   - <a-form-item label="保养明细" name="preserveDetailList">
  73 + <a-form-item label="保养明细"
  74 + name="preserveDetailList"
  75 + :label-col="{ span: 4 }"
  76 + :wrapper-col="{ span: 19 }"
  77 + >
74 78 <a-table bordered :data-source="tableData" :columns="columns">
75 79 <template #deviceInfo="{ record }">
76 80 <div>
77   - {{record?.deviceInfo.name}}
  81 + <template v-if="userInfo.isTargetTenant">
  82 + <div style="display: flex; gap: 8px">
  83 + <a-input :value="getDeviceLabel(record)" :disabled="true" placeholder="请选择" />
  84 + <a-button type="primary" @click="goChooseDevice(record)" :disabled="isViewMode">
  85 + 选设备
  86 + </a-button>
  87 + </div>
  88 + </template>
  89 + <template v-else>
  90 + {{ record?.deviceInfo?.name }}
  91 + </template>
78 92 </div>
79 93 </template>
80 94 <template #status="{ record }">
... ... @@ -116,6 +130,34 @@
116 130 </div>
117 131 </a-modal>
118 132 </a-modal>
  133 + <a-modal
  134 + v-model:visible="deviceVisible"
  135 + title="选择设备"
  136 + width="70vw"
  137 + height="60vh"
  138 + @ok="handleDeviceOk"
  139 + @cancel="handleDeviceCancel"
  140 + >
  141 + <div style="padding: 20px">
  142 + <div style="display: flex; gap: 12px; margin-bottom: 12px">
  143 + <a-input
  144 + v-model:value="deviceSearchInfo.code"
  145 + placeholder="设备位号"
  146 + allowClear
  147 + style="width: 240px"
  148 + />
  149 + <a-input
  150 + v-model:value="deviceSearchInfo.name"
  151 + placeholder="设备名称"
  152 + allowClear
  153 + style="width: 240px"
  154 + />
  155 + <a-button type="primary" @click="handleDeviceSearch">搜索</a-button>
  156 + <a-button @click="handleDeviceReset">重置</a-button>
  157 + </div>
  158 + <BasicTable @register="registerDeviceTable" />
  159 + </div>
  160 + </a-modal>
119 161 </template>
120 162 <script setup lang="ts">
121 163 // 定义 props
... ... @@ -126,6 +168,8 @@ import {getUserListByOrg} from "/@/api/equipment/ledger";
126 168 import {useUserStore} from "/@/store/modules/user";
127 169 import {serveRecordDetail} from "/@/api/inspection/serviceRecord";
128 170 import {useMessage} from "/@/hooks/web/useMessage";
  171 +import { BasicTable, useTable } from '/@/components/Table';
  172 +import { getLedgerList } from '/@/api/equipment/ledger';
129 173 const { createMessage } = useMessage();
130 174
131 175 const searchInfo = reactive<Recordable>({});
... ... @@ -191,6 +235,33 @@ const tableData = ref([...props.initialData.tableData]);
191 235 const emit = defineEmits(['update:visible', 'submit']);
192 236 const planOptions = ref([]);
193 237 const Options = ref([]);
  238 +const deviceVisible = ref(false);
  239 +const deviceSearchInfo = reactive<Recordable>({ code: '', name: '' });
  240 +const selectedDevice = ref<any>(null);
  241 +const activeDeviceRecord = ref<any>(null);
  242 +
  243 +const [registerDeviceTable, { reload: reloadDeviceTable }] = useTable({
  244 + api: getLedgerList,
  245 + columns: [
  246 + { title: '设备位号', dataIndex: 'code', width: 160 },
  247 + { title: '设备名称', dataIndex: 'name', width: 240 },
  248 + ],
  249 + searchInfo: deviceSearchInfo,
  250 + useSearchForm: false,
  251 + showTableSetting: false,
  252 + bordered: true,
  253 + showIndexColumn: false,
  254 + clickToRowSelect: false,
  255 + rowKey: 'id',
  256 + pagination: { pageSize: 10 },
  257 + rowSelection: {
  258 + type: 'radio',
  259 + onSelect: (record) => {
  260 + selectedDevice.value = record;
  261 + },
  262 + onSelectAll: () => {},
  263 + },
  264 +});
194 265 const rules = {
195 266 recordCode: [
196 267 { required: true, message: '请输入', trigger: 'blur' },
... ... @@ -258,6 +329,9 @@ const handleChange = async (value: Value) => {
258 329 preserveDetail: item?.preserveDetail || '',
259 330 deviceInfo: item?.deviceInfo || {},
260 331 preserveDetailId: item?.id || '',
  332 + deviceId: item?.deviceInfo?.id || item?.deviceId,
  333 + deviceCode: item?.deviceInfo?.code || item?.deviceCode,
  334 + deviceName: item?.deviceInfo?.name || item?.deviceName,
261 335 status: 'UNEXECUTED'
262 336 }
263 337 }) || []
... ... @@ -304,6 +378,51 @@ const fetchAgeOptions = async () => {
304 378 }
305 379 };
306 380
  381 +const getDeviceLabel = (record: any) => {
  382 + const code = record?.deviceCode;
  383 + const name = record?.deviceName;
  384 + if (code && name) return `${code} / ${name}`;
  385 + return name || code || '';
  386 +};
  387 +
  388 +const goChooseDevice = (record: any) => {
  389 + activeDeviceRecord.value = record;
  390 + selectedDevice.value = null;
  391 + deviceVisible.value = true;
  392 + reloadDeviceTable();
  393 +};
  394 +
  395 +const handleDeviceSearch = () => {
  396 + reloadDeviceTable();
  397 +};
  398 +
  399 +const handleDeviceReset = () => {
  400 + deviceSearchInfo.code = '';
  401 + deviceSearchInfo.name = '';
  402 + reloadDeviceTable();
  403 +};
  404 +
  405 +const handleDeviceOk = () => {
  406 + if (!selectedDevice.value?.id || !activeDeviceRecord.value) {
  407 + deviceVisible.value = false;
  408 + return;
  409 + }
  410 + activeDeviceRecord.value.deviceId = selectedDevice.value.id;
  411 + activeDeviceRecord.value.deviceCode = selectedDevice.value.code;
  412 + activeDeviceRecord.value.deviceName = selectedDevice.value.name;
  413 + activeDeviceRecord.value.deviceInfo = {
  414 + ...(activeDeviceRecord.value.deviceInfo || {}),
  415 + id: selectedDevice.value.id,
  416 + code: selectedDevice.value.code,
  417 + name: selectedDevice.value.name,
  418 + };
  419 + deviceVisible.value = false;
  420 +};
  421 +
  422 +const handleDeviceCancel = () => {
  423 + deviceVisible.value = false;
  424 +};
  425 +
307 426 const handleOk = () => {
308 427 if (isViewMode.value) {
309 428 visible.value = false;
... ...
... ... @@ -2,61 +2,76 @@ import { FormSchema } from '/@/components/Form';
2 2 import { useI18n } from '/@/hooks/web/useI18n';
3 3 import { BasicColumn } from '/@/components/Table';
4 4 import {getRepairOrderList} from "../../../api/repair/order";
  5 +import { useUserStore } from '/@/store/modules/user';
5 6 const { t } = useI18n();
6 7
7   -export const columns: BasicColumn[] = [
8   - {
9   - title: t('repair.history.photo'),
10   - dataIndex: 'situationImg',
11   - slots: { customRender: 'situationImg' },
12   - },
13   - {
14   - title: t('repair.history.orderCode'),
15   - dataIndex: 'code',
16   - },
17   - {
18   - title: t('repair.history.orderText'),
19   - dataIndex: 'orderCode',
20   - format: (text, record) => {
21   - return record.tkRepairOrderDTO?.orderCode || '-' || text;
  8 +export function getColumns() {
  9 + const userStore = useUserStore();
  10 + const cols: BasicColumn[] = [
  11 + {
  12 + title: t('repair.history.photo'),
  13 + dataIndex: 'situationImg',
  14 + slots: { customRender: 'situationImg' },
22 15 },
23   - },
24   - {
25   - title: t('repair.history.deviceNameText'),
26   - dataIndex: 'deviceAccountName',
27   - },
28   - {
29   - title: t('repair.history.time'),
30   - dataIndex: 'reportDate',
31   - format: (text, record) => {
32   - return record.tkRepairOrderDTO?.reportDate || '-' || text;
  16 + {
  17 + title: t('repair.history.orderCode'),
  18 + dataIndex: 'code',
33 19 },
34   - },
35   - {
36   - title: t('repair.history.reportByName'),
37   - dataIndex: 'tkRepairOrderDTO',
38   - format: (text, record) => {
39   - return record.tkRepairOrderDTO?.reportByName || '-' || text;
  20 + {
  21 + title: t('repair.history.orderText'),
  22 + dataIndex: 'orderCode',
  23 + format: (text, record) => {
  24 + return record.tkRepairOrderDTO?.orderCode || '-' || text;
  25 + },
40 26 },
41   - },
  27 + {
  28 + title: t('repair.history.deviceNameText'),
  29 + dataIndex: 'deviceAccountName',
  30 + },
  31 + {
  32 + title: t('repair.history.time'),
  33 + dataIndex: 'reportDate',
  34 + format: (text, record) => {
  35 + return record.tkRepairOrderDTO?.reportDate || '-' || text;
  36 + },
  37 + },
  38 + {
  39 + title: t('repair.history.reportByName'),
  40 + dataIndex: 'tkRepairOrderDTO',
  41 + format: (text, record) => {
  42 + return record.tkRepairOrderDTO?.reportByName || '-' || text;
  43 + },
  44 + },
  45 + {
  46 + title: t('repair.history.description'),
  47 + dataIndex: 'description',
  48 + },
  49 + {
  50 + title: t('repair.history.repairTime'),
  51 + dataIndex: 'repairDate',
  52 + },
  53 + {
  54 + title: t('repair.history.repairByName'),
  55 + dataIndex: 'repairName',
  56 + },
  57 + {
  58 + title: t('repair.history.repairReason'),
  59 + dataIndex: 'malfunctionReasonName',
  60 + },
  61 + ];
42 62
43   - {
44   - title: t('repair.history.description'),
45   - dataIndex: 'description',
46   - },
47   - {
48   - title: t('repair.history.repairTime'),
49   - dataIndex: 'repairDate',
50   - },
51   - {
52   - title: t('repair.history.repairByName'),
53   - dataIndex: 'repairName',
54   - },
55   - {
56   - title: t('repair.history.repairReason'),
57   - dataIndex: 'malfunctionReasonName',
58   - },
59   -];
  63 + if (userStore.isTargetTenant) {
  64 + const deviceNameIndex = cols.findIndex((c) => c.dataIndex === 'deviceAccountName');
  65 + if (deviceNameIndex !== -1) {
  66 + cols.splice(deviceNameIndex, 0, {
  67 + title: '设备位号',
  68 + dataIndex: 'deviceAccountCode',
  69 + });
  70 + }
  71 + }
  72 +
  73 + return cols;
  74 +}
60 75
61 76 export const searchFormSchema: FormSchema[] = [
62 77 {
... ...
... ... @@ -19,7 +19,7 @@
19 19 <script setup lang="ts">
20 20 import { BasicTable, useTable, TableImg } from '/@/components/Table';
21 21 import { getRepairHistoryList } from '/@/api/repair/history';
22   - import { columns, searchFormSchema } from "./index"
  22 + import { getColumns, searchFormSchema } from "./index"
23 23 import { useI18n } from '/@/hooks/web/useI18n';
24 24 const { t } = useI18n();
25 25 const [
... ... @@ -28,7 +28,7 @@
28 28 ] = useTable({
29 29 title: t('repair.history.listText'),
30 30 api: getRepairHistoryList,
31   - columns,
  31 + columns: getColumns(),
32 32 formConfig: {
33 33 labelWidth: 100,
34 34 schemas: searchFormSchema,
... ...
... ... @@ -11,8 +11,24 @@
11 11 >
12 12 <div>
13 13 <BasicForm @register="registerForm" />
  14 + <div
  15 + v-if="userInfo.isTargetTenant"
  16 + style="display: flex; width: 70%; margin-left: 70px; margin-bottom: 18px"
  17 + >
  18 + <div
  19 + style="display: flex; width: 130px; align-content: center; justify-content: center"
  20 + class="inputTitle"
  21 + >
  22 + 设备
  23 + </div>
  24 + <a-input placeholder="请选择" :disabled="true" v-model:value="selectedDeviceLabel" />
  25 + <a-button type="primary" @click="goChooseDevice">选设备</a-button>
  26 + </div>
14 27 <div style="display: flex; width: 70%; margin-left: 70px">
15   - <div style="display: flex;width: 115px;align-content: center;justify-content: center;" class="inputTitle">
  28 + <div
  29 + style="display: flex; width: 118px; align-content: center; justify-content: center"
  30 + class="inputTitle"
  31 + >
16 32 报修人
17 33 </div>
18 34 <a-input placeholder="请选择" :disabled="true" v-model:value="selectedUsername" />
... ... @@ -38,6 +54,34 @@
38 54 </div>
39 55 </div>
40 56 </a-modal>
  57 + <a-modal
  58 + v-model:visible="deviceVisible"
  59 + title="选择设备"
  60 + width="70vw"
  61 + height="40vh"
  62 + @ok="handleDeviceOk"
  63 + @cancel="handleDeviceCancel"
  64 + >
  65 + <div style="padding: 20px">
  66 + <div style="display: flex; gap: 12px; margin-bottom: 12px">
  67 + <a-input
  68 + v-model:value="deviceSearchInfo.code"
  69 + placeholder="请输入设备位号"
  70 + allowClear
  71 + style="width: 240px"
  72 + />
  73 + <a-input
  74 + v-model:value="deviceSearchInfo.name"
  75 + placeholder="请输入设备名称"
  76 + allowClear
  77 + style="width: 240px"
  78 + />
  79 + <a-button type="primary" @click="handleDeviceSearch">搜索</a-button>
  80 + <a-button @click="handleDeviceReset">重置</a-button>
  81 + </div>
  82 + <BasicTable @register="registerDeviceTable" />
  83 + </div>
  84 + </a-modal>
41 85 </BasicModal>
42 86 </div>
43 87 </template>
... ... @@ -52,6 +96,8 @@
52 96 import { saveOrder } from '/@/api/repair/order';
53 97 import { useMessage } from '/@/hooks/web/useMessage';
54 98 import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree';
  99 + import { BasicTable, useTable } from '/@/components/Table';
  100 + import { getLedgerList } from '/@/api/equipment/ledger';
55 101 const { t } = useI18n();
56 102 const isUpdate = ref<Boolean>(false);
57 103 const recordInfo = ref<any>({});
... ... @@ -66,6 +112,9 @@
66 112 const userVisible = ref(false);
67 113 const userModalTitle = ref('选人');
68 114 const selectedItem = ref<{ id: string; username: string } | null>(null);
  115 + const deviceVisible = ref(false);
  116 + const deviceSearchInfo = reactive<Recordable>({ code: '', name: '' });
  117 + const selectedDevice = ref<any>(null);
69 118 const radioStyle = reactive({
70 119 display: 'block',
71 120 height: '30px',
... ... @@ -81,6 +130,16 @@
81 130 },
82 131 });
83 132
  133 + const selectedDeviceLabel = computed({
  134 + get: () => {
  135 + const code = selectedDevice.value?.code;
  136 + const name = selectedDevice.value?.name;
  137 + if (code && name) return `${code} / ${name}`;
  138 + return name || code || '';
  139 + },
  140 + set: () => {},
  141 + });
  142 +
84 143 const emit = defineEmits(['handleReload', 'register']);
85 144
86 145 const getTitle = computed(() =>
... ... @@ -96,6 +155,29 @@
96 155 showActionButtonGroup: false,
97 156 });
98 157
  158 + const [registerDeviceTable, { reload: reloadDeviceTable }] = useTable({
  159 + api: getLedgerList,
  160 + columns: [
  161 + { title: '设备位号', dataIndex: 'code', width: 160 },
  162 + { title: '设备名称', dataIndex: 'name', width: 240 },
  163 + ],
  164 + searchInfo: deviceSearchInfo,
  165 + useSearchForm: false,
  166 + showTableSetting: false,
  167 + bordered: true,
  168 + showIndexColumn: false,
  169 + clickToRowSelect: false,
  170 + rowKey: 'id',
  171 + pagination: { pageSize: 10 },
  172 + rowSelection: {
  173 + type: 'radio',
  174 + onSelect: (record) => {
  175 + selectedDevice.value = record;
  176 + },
  177 + onSelectAll: () => {},
  178 + },
  179 + });
  180 +
99 181 const [register, { closeModal, setModalProps }] = useModalInner(async (data) => {
100 182 setModalProps({ confirmLoading: false, loading: true });
101 183 isUpdate.value = data?.isUpdate;
... ... @@ -111,6 +193,27 @@
111 193 onChange: handleOrgChange,
112 194 },
113 195 });
  196 + if (userInfo.isTargetTenant) {
  197 + updateSchema({
  198 + field: 'deviceId',
  199 + ifShow: false,
  200 + });
  201 + selectedDevice.value = data?.record?.deviceInfo
  202 + ? {
  203 + id: data?.record?.deviceId,
  204 + name: data?.record?.deviceInfo?.name,
  205 + code: data?.record?.deviceInfo?.code,
  206 + }
  207 + : data?.record?.deviceId
  208 + ? { id: data?.record?.deviceId, name: '' }
  209 + : null;
  210 + } else {
  211 + updateSchema({
  212 + field: 'deviceId',
  213 + ifShow: true,
  214 + });
  215 + selectedDevice.value = null;
  216 + }
114 217 if (data?.record) {
115 218 setFieldsValue(data?.record);
116 219 }
... ... @@ -154,6 +257,10 @@
154 257 const handleOk = async () => {
155 258 await validate();
156 259 let values = getFieldsValue();
  260 + if (userInfo.isTargetTenant && !selectedDevice.value?.id) {
  261 + createMessage.warning('请选择设备');
  262 + return;
  263 + }
157 264 if (!selectedItem?.value?.id) {
158 265 createMessage.warning('请选择报修人');
159 266 return;
... ... @@ -172,6 +279,9 @@
172 279 reportBy: selectedItem.value?.id || '',
173 280 };
174 281 }
  282 + if (userInfo.isTargetTenant) {
  283 + values = { ...values, deviceId: selectedDevice.value?.id };
  284 + }
175 285 await saveOrder(values);
176 286 createMessage.success(t('common.operationSuccessText'));
177 287 emit('handleReload');
... ... @@ -183,6 +293,34 @@
183 293 selectedItem.value = null;
184 294 };
185 295
  296 + const goChooseDevice = () => {
  297 + deviceVisible.value = true;
  298 + reloadDeviceTable();
  299 + };
  300 +
  301 + const handleDeviceSearch = () => {
  302 + reloadDeviceTable();
  303 + };
  304 +
  305 + const handleDeviceReset = () => {
  306 + deviceSearchInfo.code = '';
  307 + deviceSearchInfo.name = '';
  308 + reloadDeviceTable();
  309 + };
  310 +
  311 + const handleDeviceOk = async () => {
  312 + if (!selectedDevice.value?.id) {
  313 + createMessage.warning('请选择设备');
  314 + return;
  315 + }
  316 + await setFieldsValue({ deviceId: selectedDevice.value.id });
  317 + deviceVisible.value = false;
  318 + };
  319 +
  320 + const handleDeviceCancel = () => {
  321 + deviceVisible.value = false;
  322 + };
  323 +
186 324 // 确认按钮的回调
187 325 const handleUserOk = () => {
188 326 if (!selectedItem.value) {
... ...
... ... @@ -19,72 +19,112 @@ const emergencyOptions = [
19 19 { label: '否', value: false },
20 20 ];
21 21
22   -export const columns: BasicColumn[] = [
23   - {
24   - title: t('repair.order.situationImg'),
25   - dataIndex: 'situationImg',
26   - slots: { customRender: 'situationImg' },
27   - },
28   - {
29   - title: t('repair.order.nameCode'),
30   - dataIndex: 'orderCode',
31   - },
32   - {
33   - title: t('repair.order.deviceNameText'),
34   - dataIndex: 'deviceId',
35   - slots: { customRender: 'deviceId' },
36   - },
37   - {
38   - title: t('repair.order.reportDateText'),
39   - dataIndex: 'reportDate',
40   - },
41   - {
42   - title: t('repair.order.reportByName'),
43   - dataIndex: 'reportByName',
44   - },
45   - {
46   - title: t('repair.order.description'),
47   - dataIndex: 'description',
48   - },
49   - {
50   - title: t('repair.order.statusText'),
51   - dataIndex: 'status',
52   - slots: { customRender: 'status' },
53   - },
54   - {
55   - title: t('repair.order.emergencyText'),
56   - dataIndex: 'emergency',
57   - slots: { customRender: 'emergency' },
58   - },
59   -];
  22 +export function getColumns(isTargetTenant: boolean): BasicColumn[] {
  23 + const cols: BasicColumn[] = [
  24 + {
  25 + title: t('repair.order.situationImg'),
  26 + dataIndex: 'situationImg',
  27 + slots: { customRender: 'situationImg' },
  28 + },
  29 + {
  30 + title: t('repair.order.nameCode'),
  31 + dataIndex: 'orderCode',
  32 + },
  33 + {
  34 + title: t('repair.order.deviceNameText'),
  35 + dataIndex: 'deviceId',
  36 + slots: { customRender: 'deviceId' },
  37 + },
  38 + {
  39 + title: t('repair.order.reportDateText'),
  40 + dataIndex: 'reportDate',
  41 + },
  42 + {
  43 + title: t('repair.order.reportByName'),
  44 + dataIndex: 'reportByName',
  45 + },
  46 + {
  47 + title: t('repair.order.description'),
  48 + dataIndex: 'description',
  49 + },
  50 + {
  51 + title: t('repair.order.statusText'),
  52 + dataIndex: 'status',
  53 + slots: { customRender: 'status' },
  54 + },
  55 + {
  56 + title: t('repair.order.emergencyText'),
  57 + dataIndex: 'emergency',
  58 + slots: { customRender: 'emergency' },
  59 + },
  60 + ];
60 61
61   -export const searchFormSchema: FormSchema[] = [
62   - {
63   - field: 'deviceId',
64   - label: t('repair.order.deviceNameText'),
65   - component: 'ApiSelect',
66   - colProps: { span: 6 },
67   - componentProps: {
68   - api: getLedgerList,
69   - params: {
70   - page: 1,
71   - pageSize: 999,
  62 + if (isTargetTenant) {
  63 + const deviceIndex = cols.findIndex((c) => c.dataIndex === 'deviceId');
  64 + if (deviceIndex !== -1) {
  65 + cols.splice(deviceIndex, 0, {
  66 + title: '设备位号',
  67 + dataIndex: 'deviceCode',
  68 + slots: { customRender: 'deviceCode' },
  69 + });
  70 + }
  71 + }
  72 +
  73 + return cols;
  74 +}
  75 +
  76 +export function getSearchFormSchema(isTargetTenant: boolean): FormSchema[] {
  77 + const schema: FormSchema[] = [
  78 + {
  79 + field: 'deviceId',
  80 + label: t('repair.order.deviceNameText'),
  81 + component: 'ApiSelect',
  82 + colProps: { span: 6 },
  83 + ifShow: !isTargetTenant,
  84 + componentProps: {
  85 + api: getLedgerList,
  86 + params: {
  87 + page: 1,
  88 + pageSize: 999,
  89 + },
  90 + resultField: 'items',
  91 + labelField: 'name',
  92 + valueField: 'id',
72 93 },
73   - resultField: 'items',
74   - labelField: 'name',
75   - valueField: 'id',
76 94 },
77   - },
78   - {
79   - field: 'status',
80   - label: t('repair.order.statusText'),
81   - component: 'Select',
82   - colProps: { span: 6 },
83   - componentProps: {
84   - options: statusOptions,
  95 + {
  96 + field: 'deviceCode',
  97 + label: '设备位号',
  98 + component: 'Input',
  99 + colProps: { span: 6 },
  100 + ifShow: isTargetTenant,
  101 + componentProps: {
  102 + maxLength: 255,
  103 + },
85 104 },
86   - },
87   -];
  105 + {
  106 + field: 'deviceName',
  107 + label: t('repair.order.deviceNameText'),
  108 + component: 'Input',
  109 + colProps: { span: 6 },
  110 + ifShow: isTargetTenant,
  111 + componentProps: {
  112 + maxLength: 255,
  113 + },
  114 + },
  115 + {
  116 + field: 'status',
  117 + label: t('repair.order.statusText'),
  118 + component: 'Select',
  119 + colProps: { span: 6 },
  120 + componentProps: {
  121 + options: statusOptions,
  122 + },
  123 + },
  124 + ];
  125 +
  126 + return schema;
  127 +}
88 128
89 129 export const schemas: FormSchema[] = [
90 130 {
... ...
... ... @@ -23,6 +23,9 @@
23 23 <template #deviceId="{ record }">
24 24 <span>{{ record?.deviceInfo?.name }}</span>
25 25 </template>
  26 + <template #deviceCode="{ record }">
  27 + <span>{{ record?.deviceInfo?.code }}</span>
  28 + </template>
26 29 <template #status="{ record }">
27 30 <Tag
28 31 :color="
... ... @@ -86,11 +89,12 @@
86 89 import { BasicTable, TableAction, TableImg } from '/@/components/Table';
87 90 import { useTable } from '/@/components/Table';
88 91 import {getRepairOrderList, saveRecord, updateStatus} from '/@/api/repair/order';
89   - import { columns, searchFormSchema } from './index';
  92 + import { getColumns, getSearchFormSchema } from './index';
90 93 import { useI18n } from '/@/hooks/web/useI18n';
91 94 import { Button, Tag } from 'ant-design-vue';
92 95 import { Authority } from '/@/components/Authority';
93 96 import {useModal} from "/@/components/Modal";
  97 + import { useUserStore } from '/@/store/modules/user';
94 98 const { t } = useI18n();
95 99 const [registerModal, { openModal }] = useModal();
96 100 import {FormDrawer} from "./components/FormDrawer/index";
... ... @@ -101,6 +105,7 @@
101 105 const modalVisible = ref(false);
102 106 const [registerApplicationApiFormDrawer, { }] = useDrawer();
103 107 const { createMessage } = useMessage();
  108 + const userStore = useUserStore();
104 109 const initialData = ref({
105 110 form: {
106 111 orderId:'',
... ... @@ -117,10 +122,10 @@
117 122 ] = useTable({
118 123 title: t('repair.order.listText'),
119 124 api: getRepairOrderList,
120   - columns,
  125 + columns: getColumns(userStore.isTargetTenant),
121 126 formConfig: {
122 127 labelWidth: 100,
123   - schemas: searchFormSchema,
  128 + schemas: getSearchFormSchema(userStore.isTargetTenant),
124 129 },
125 130 immediate: true,
126 131 useSearchForm: true,
... ...