@brms/ai-skills 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +256 -0
  2. package/bin/brms-skills.mjs +411 -0
  3. package/package.json +30 -0
  4. package/skills/brms-prototype-generator/SKILL.md +129 -0
  5. package/skills/brms-prototype-generator/agents/openai.yaml +7 -0
  6. package/skills/brms-prototype-generator/examples/few-shot-examples.md +577 -0
  7. package/skills/brms-prototype-generator/references/01-list-query.md +444 -0
  8. package/skills/brms-prototype-generator/references/02-form-entry.md +129 -0
  9. package/skills/brms-prototype-generator/references/03-detail-display.md +125 -0
  10. package/skills/brms-prototype-generator/references/04-composite-page-package.md +339 -0
  11. package/skills/brms-prototype-generator/references/05-dialog-patterns.md +113 -0
  12. package/skills/brms-prototype-generator/references/06-backend-request-patterns.md +118 -0
  13. package/skills/brms-prototype-generator/references/resource-index.md +46 -0
  14. package/skills/brms-prototype-generator/references/system-prompt.md +242 -0
  15. package/skills/brms-prototype-generator/scripts/analyze-doc.mjs +554 -0
  16. package/skills/brms-prototype-generator/scripts/check-project.mjs +228 -0
  17. package/skills/brms-prototype-generator/scripts/discover-targets.mjs +158 -0
  18. package/skills/brms-prototype-generator/scripts/install-codex.mjs +74 -0
  19. package/skills/brms-prototype-generator/scripts/plan-pages.mjs +390 -0
  20. package/skills/brms-prototype-generator/scripts/validate-generated.mjs +838 -0
  21. package/skills/brms-prototype-generator/templates/user-input-template.md +182 -0
  22. package/skills/brms-vxe-plus-developer/SKILL.md +105 -0
  23. package/skills/brms-vxe-plus-developer/agents/openai.yaml +7 -0
  24. package/skills/brms-vxe-plus-developer/references/prototype-to-real.md +54 -0
  25. package/skills/brms-vxe-plus-developer/references/real-base-development.md +110 -0
  26. package/skills/brms-vxe-plus-developer/references/resource-index.md +43 -0
  27. package/skills/brms-vxe-plus-developer/references/review-checklist.md +49 -0
  28. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/01-mental-model.md +150 -0
  29. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/02-vxe-plus-form.md +302 -0
  30. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/03-vxe-plus-table.md +253 -0
  31. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/04-example-map.md +488 -0
  32. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/05-request-and-eiinfo.md +170 -0
  33. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/90-anti-patterns.md +137 -0
  34. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/README.md +43 -0
  35. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/README.md +21 -0
  36. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/A1/P0/A1P01601.vue +483 -0
  37. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/A1/P1/A1P11011.vue +444 -0
  38. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/AB/BP/ABBP0201.vue +1648 -0
  39. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/AM/AF/component/AMAF0601/Bidding/formConfig.ts +228 -0
  40. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/AM/AF/component/AMAF0601/Record/columns.ts +110 -0
  41. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/BM/BR/BMBR01.vue +130 -0
  42. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/BM/BR/component/BMBR01/columns.ts +94 -0
  43. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/BM/BR/component/BMBR01/formConfig.ts +108 -0
  44. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Change/formConfig.ts +123 -0
  45. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Change/index.vue +103 -0
  46. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Clause/columns.ts +48 -0
  47. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Clause/index.vue +202 -0
  48. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Correcte/formConfig.ts +117 -0
  49. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Correcte/index.vue +103 -0
  50. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Pay/Payment/formConfig.ts +90 -0
  51. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Pay/Payment/index.vue +42 -0
  52. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Pay/columns.ts +376 -0
  53. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Pay/index.vue +619 -0
  54. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/Domestic/formConfig.ts +73 -0
  55. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/Domestic/index.vue +47 -0
  56. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/Foreign/formConfig.ts +141 -0
  57. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/Foreign/index.vue +42 -0
  58. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/columns.ts +123 -0
  59. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/Settle/index.vue +593 -0
  60. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Explain/index.vue +68 -0
  61. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Fee/columns.ts +150 -0
  62. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Fee/index.vue +235 -0
  63. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Files/columns.ts +63 -0
  64. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Files/index.vue +117 -0
  65. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Goods/columns.ts +327 -0
  66. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Goods/index.vue +790 -0
  67. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Approve/formConfig.ts +341 -0
  68. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Approve/index.vue +63 -0
  69. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Approve2/formConfig.ts +232 -0
  70. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Approve2/index.vue +27 -0
  71. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Diff/columns.ts +46 -0
  72. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/Diff/index.vue +92 -0
  73. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/formConfig.ts +979 -0
  74. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Base/index.vue +62 -0
  75. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Other/formConfig.ts +179 -0
  76. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Other/index.vue +140 -0
  77. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Sign/formConfig.ts +118 -0
  78. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/Sign/index.vue +44 -0
  79. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Main/index.vue +168 -0
  80. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Party/Major/formConfig.ts +257 -0
  81. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Party/Major/index.vue +47 -0
  82. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Party/columns.ts +256 -0
  83. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Party/index.vue +738 -0
  84. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Price/formConfig.ts +174 -0
  85. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Price/index.vue +51 -0
  86. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/PM/PC/component/PMPC0101/Top/index.vue +924 -0
  87. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/SM/SW/SMSW0101.vue +567 -0
  88. package/skills/brms-vxe-plus-developer/references/vxe-plus-knowledge/sources/project/base/src/views/demo/index.vue +448 -0
  89. package/skills/brms-vxe-plus-developer/scripts/check-project.mjs +259 -0
  90. package/skills/brms-vxe-plus-developer/scripts/check-vxe-plus-page.mjs +137 -0
@@ -0,0 +1,790 @@
1
+ <template>
2
+ <BxRoundedContainer>
3
+ <BxContainer ref="container" title="商品信息">
4
+ <VxePlusTable
5
+ :id="tablePageId"
6
+ ref="xGrid"
7
+ class="pb0"
8
+ :columns="columns"
9
+ :auto-load="autoLoad"
10
+ :show-checkbox="editable"
11
+ :is-edit="editable"
12
+ :edit-rules="editRules"
13
+ :left-buttons="['ADD_CONTRACT_GOODS']"
14
+ :service-config="serviceConfig"
15
+ :transform-params="transformParams"
16
+ :transform-response="transformResponse"
17
+ :loading="loading"
18
+ :toolbar-buttons="toolbarButtons"
19
+ :after-load="afterLoad"
20
+ :span-method="rowspanMethod"
21
+ :virtual-x-config="{ enabled: false }"
22
+ :virtual-y-config="{ enabled: false }"
23
+ :checkbox-config="{
24
+ visibleMethod: ({ row }) => !(diffable && row.diffable),
25
+ checkMethod: ({ row }) => !(diffable && row.diffable),
26
+ }"
27
+ :before-edit-method="({ row }) => editable && !(diffable && row.diffable)"
28
+ min-height="179px"
29
+ max-height="403px"
30
+ v-on="gridEvents"
31
+ >
32
+ <template #goodsCode_header="{ column }">
33
+ <span v-if="editable" class="vxe-cell--required-icon">
34
+ <i />
35
+ </span>
36
+ <span>{{ column.title }}</span>
37
+ </template>
38
+ <template #quantityPurchase_header="{ column }">
39
+ <span v-if="editable" class="vxe-cell--required-icon">
40
+ <i />
41
+ </span>
42
+ <span>{{ column.title }}</span>
43
+ </template>
44
+ <template #priceTax_header="{ column }">
45
+ <span v-if="editable" class="vxe-cell--required-icon">
46
+ <i />
47
+ </span>
48
+ <span>{{ column.title }}</span>
49
+ </template>
50
+ <template #moreAndLessRatio_header="{ column }">
51
+ <span v-if="editable" class="vxe-cell--required-icon">
52
+ <i />
53
+ </span>
54
+ <span>{{ column.title }}</span>
55
+ </template>
56
+ <template #destinationPlace_header="{ column }">
57
+ <span v-if="editable" class="vxe-cell--required-icon">
58
+ <i />
59
+ </span>
60
+ <span>{{ column.title }}</span>
61
+ </template>
62
+ <template v-for="column in columns" #[column.slots.default]="{ row }">
63
+ <span v-if="['goodsName'].includes(column.field)" :key="`${column.field}-cell-1`" :class="{ 'text-blue-500 cursor-pointer underline': !isApprovePage, 'text-red-500 line-through-1': diffable && row.diffable && row[`${column.field}__diffable`] }" @click="handleEdit(row)">{{ row.goodsName }}</span>
64
+ <span v-else-if="['priceInstanceName'].includes(column.field)" :key="`${column.field}-cell`" :class="{ 'text-blue-500 cursor-pointer underline': !isApprovePage, 'text-red-500 line-through-1': diffable && row.diffable && row[`${column.field}__diffable`] }" @click="handleFormulaInfo(row)">{{ row.priceInstanceName }}</span>
65
+ <span v-else-if="column.editRender?.name === 'tableSelect'" :key="`${column.field}-tableSelect`" :class="diffable && row.diffable && row[`${column.field}__diffable`] && 'text-red-500 line-through-1'">{{ getCodeSetTextByCode(column.editRender?.props?.codeSet, row[column.field]) }}</span>
66
+ <span v-else-if="column.formatter" :key="`${column.field}-formatter`" :class="diffable && row.diffable && row[`${column.field}__diffable`] && 'text-red-500 line-through-1'">{{ column.formatter({ row, cellValue: row[column.field] }) }}</span>
67
+ <span v-else :key="`${column.field}`" :class="diffable && row.diffable && row[`${column.field}__diffable`] && 'text-red-500 line-through-1'">{{ row[column.field] }}</span>
68
+ </template>
69
+ </VxePlusTable>
70
+ </BxContainer>
71
+ </BxRoundedContainer>
72
+ </template>
73
+
74
+ <script setup lang="ts">
75
+ import { computed, inject, nextTick, reactive, ref, toValue, watch } from 'vue'
76
+ import type { Ref } from 'vue'
77
+ import type { EiInfo } from '@eplat/ei'
78
+ import type { VxeGridProps } from 'vxe-table'
79
+ import XEUtils, { has, multiply } from 'xe-utils'
80
+ import Qs from 'qs'
81
+ import { ElMessage, ElMessageBox } from 'element-plus'
82
+ import { useDialog } from '@vxe-plus/components'
83
+ import dayjs from 'dayjs'
84
+ import { createTableColumns } from './columns'
85
+ import { createEiBlock, sendService } from '@/utils/eiTools'
86
+ import { isEmpty, isNumber } from '@/utils/is'
87
+ import { compareData, generateId, openV6Page, scrollIntoView } from '@/utils'
88
+ import { useCodeSetStore } from '@/stores/modules/codeSet'
89
+ import { useFileUpload } from '@/hooks/useFileUpload'
90
+ import PMPC9701 from '@/views/PM/PC/PMPC9701.vue'
91
+ import JMJR0101 from '@/views/JM/JR/JMJR0101.vue'
92
+
93
+ const xGrid = ref<any>(null)
94
+ const container = ref<any>(null)
95
+
96
+ const { addable, editable, detailInfo, businessType, contractType, diffable, pageId, isCorrecte, isCorrecteOrChange, foreignFlag, isFirstVersion, attrInfo, hedgingFlag, isApprovePage, isHistory } = inject('__PMPC0101__info__') as any
97
+
98
+ const { updateDetailInfo, fetchDetailInfo, saveDetail, getId } = inject('__PMPC0101__method__') as any
99
+
100
+ const { main: mainModule, price: priceModule, party: partyModule } = inject('__PMPC0101__module__') as { main: Ref, price: Ref, party: Ref }
101
+
102
+ const baseModule = computed(() => mainModule?.value?.base)
103
+
104
+ const baseModuleFormData = computed(() => baseModule?.value?.formData)
105
+
106
+ const priceModuleFormData = computed(() => priceModule?.value?.formData)
107
+
108
+ const isPriceTax = computed(() => {
109
+ if (!isApprovePage.value) {
110
+ return priceModuleFormData.value?.priceTaxFlag
111
+ }
112
+ return detailInfo.value?.priceTaxFlag
113
+ })
114
+
115
+ const initLoadEiInfo = toValue(inject<Ref<EiInfo> | undefined>('__eiInfo__', undefined))
116
+
117
+ const standardFlag = computed(() => addable.value ? initLoadEiInfo?.get('standardFlag') : attrInfo.value?.standardFlag)
118
+
119
+ const { getCodeSetTextByCode } = useCodeSetStore()
120
+
121
+ const { columns, editRules, tableValidator } = createTableColumns() as any
122
+
123
+ const autoLoad = computed(() => !!detailInfo.value[getId('pcContractMainId')])
124
+
125
+ const tablePageId = computed(() => `${pageId.value}_result_2`)
126
+
127
+ const toolbarButtons = ref<NonNullable<VxeGridProps['toolbarConfig']>['buttons']>([
128
+ {
129
+ name: '查看合同文本',
130
+ code: 'VIEW_TEXT',
131
+ },
132
+ {
133
+ name: '查看合同详情',
134
+ code: 'VIEW_DETAIL',
135
+ },
136
+ ])
137
+
138
+ function getTableData() {
139
+ const $grid = xGrid.value.getGridInstance()
140
+ const { tableData } = $grid.getTableData()
141
+ if (diffable.value) {
142
+ return tableData.filter(row => !row.diffable)
143
+ }
144
+ return tableData
145
+ }
146
+
147
+ function scrollIntoTop() {
148
+ scrollIntoView(container.value.$el)
149
+ }
150
+
151
+ async function handleValidator(flag?, tableFlag: boolean = false) {
152
+ try {
153
+ if (flag !== false && tableFlag) {
154
+ const tableData = getTableData()
155
+ if (!tableData.length) {
156
+ scrollIntoTop()
157
+ ElMessage.warning('至少需要1条商品信息')
158
+ return Promise.reject(false)
159
+ }
160
+ }
161
+ await tableValidator(xGrid, flag ?? diffable.value ? getTableData() : true)
162
+ return Promise.resolve(true)
163
+ }
164
+ catch (error) {
165
+ return Promise.reject(error)
166
+ }
167
+ }
168
+
169
+ function reload() {
170
+ xGrid.value.reload()
171
+ }
172
+
173
+ const serviceConfig = reactive({
174
+ serviceName: isCorrecteOrChange.value ? 'PMPC9701' : isFirstVersion.value ? 'PMPC0102' : 'PMPC0101',
175
+ queryMethod: isCorrecteOrChange.value ? 'queryContractGoodsComparesForVue' : 'queryContractGoods',
176
+ })
177
+
178
+ function transformParams(formEi) {
179
+ formEi.set(`inqu_status-0-pcContractMainId`, detailInfo.value.pcContractMainId)
180
+ formEi.set(`inqu_status-0-${getId('pcContractMainId')}`, detailInfo.value[getId('pcContractMainId')])
181
+ if (isFirstVersion.value) {
182
+ formEi.set(`inqu_status-0-operateType`, '10')
183
+ }
184
+ return formEi
185
+ }
186
+
187
+ function transformResponse(data) {
188
+ return (data || []).map((item) => {
189
+ item.priceTax = isPriceTax.value === 'Y' ? item.priceWithtax : isPriceTax.value === 'N' ? item.priceNotax : ''
190
+ const ratio = [] as any
191
+ if (!isEmpty(item.moreRatio)) {
192
+ ratio.push({
193
+ symbol: '+',
194
+ value: item.moreRatio,
195
+ })
196
+ }
197
+ else {
198
+ ratio.push('')
199
+ }
200
+ if (!isEmpty(item.lessRatio)) {
201
+ ratio.push({
202
+ symbol: '-',
203
+ value: item.lessRatio,
204
+ })
205
+ }
206
+ else {
207
+ ratio.push('')
208
+ }
209
+ item.moreAndLessRatio = ratio.some(value => !isEmpty(value))
210
+ ? ratio.map((k) => {
211
+ return !isEmpty(k) ? `${k.symbol}${XEUtils.toFixed(multiply(Number.parseFloat(k.value), 100), 2)}%` : ''
212
+ }).join('~')
213
+ : ''
214
+ if (diffable.value && isEmpty(item.operateType)) {
215
+ item.operateType = `${isCorrecte.value ? '修正' : '变更'}后`
216
+ }
217
+ return item
218
+ })
219
+ }
220
+
221
+ const isInit = ref(true)
222
+
223
+ function refresh() {
224
+ isInit.value = false
225
+ reload()
226
+ partyModule?.value?.reload()
227
+ }
228
+
229
+ function rowspanMethod({ row, _rowIndex, column, visibleData }) {
230
+ if (diffable.value) {
231
+ const fields = ['pcContractGoodsId']
232
+ if (editable.value) {
233
+ fields.push('checkbox')
234
+ }
235
+ const cellValue = row[column.field]
236
+ const isCheckbox = column.field === 'checkbox'
237
+ const flag = isCheckbox ? ['D', 'U'].includes(row.operationType) : true
238
+ if (cellValue && fields.includes(column.field) && flag) {
239
+ const prevRow = visibleData[_rowIndex - 1]
240
+ let nextRow = visibleData[_rowIndex + 1]
241
+ if (prevRow && prevRow[column.field] === cellValue) {
242
+ return { rowspan: 0, colspan: 0 }
243
+ }
244
+ else {
245
+ let countRowspan = 1
246
+ while (nextRow && nextRow[column.field] === cellValue) {
247
+ nextRow = visibleData[++countRowspan + _rowIndex]
248
+ }
249
+ if (countRowspan > 1) {
250
+ return { rowspan: countRowspan, colspan: 1 }
251
+ }
252
+ }
253
+ }
254
+ }
255
+ }
256
+
257
+ const loading = ref(!!detailInfo.value[getId('pcContractMainId')] && diffable.value)
258
+
259
+ // 获取diff数据
260
+ async function getDiffData(data, rowId) {
261
+ if (!diffable.value) {
262
+ return
263
+ }
264
+ if (data && data.length) {
265
+ try {
266
+ loading.value = true
267
+ const diffResult = await sendService({
268
+ serviceName: 'PMPC9701',
269
+ methodName: 'queryContractGoodsForVue',
270
+ eiBlocks: [
271
+ createEiBlock({
272
+ [getId('pcContractMainId')]: detailInfo.value[getId('pcContractMainId')],
273
+ }, 'inqu_status'),
274
+ ],
275
+ blockName: 'result_2',
276
+ loading: false,
277
+ }) as any
278
+ console.log('diffResult', diffResult)
279
+ const rowHisId = getId(rowId)
280
+ const excludes = ['operationType', 'operateType', 'custom', rowId, rowHisId]
281
+ const deleteRows = data.filter(row => ['D'].includes(row.operationType)).map((item) => {
282
+ const diffData = columns.value.reduce((ob, column) => {
283
+ const field = column.field
284
+ if (!excludes.includes(field)) {
285
+ ob[`${field}__diffable`] = true
286
+ }
287
+ return ob
288
+ }, {})
289
+ return {
290
+ ...item,
291
+ ...diffData,
292
+ diffable: true,
293
+ }
294
+ })
295
+ const diffList = transformResponse(diffResult || []).filter(row => !isEmpty(row[rowId]))
296
+ let newRows = [] as any[]
297
+ if (diffList && diffList.length) {
298
+ const updateRowsOb = data.filter(row => ['U'].includes(row.operationType)).reduce((updateOb, row) => {
299
+ const originRows = diffList.filter(item => item[rowId] === row[rowId]).map((originRow) => {
300
+ const diffData = columns.value.reduce((ob, column) => {
301
+ const field = column.field
302
+ if (has(originRow, field) && !excludes.includes(field)) {
303
+ const originValue = originRow[field]
304
+ const currentValue = row[field]
305
+ if (isNumber(originValue) && isNumber(currentValue)) {
306
+ if (Number(originValue) !== Number(currentValue)) {
307
+ ob[`${field}__diffable`] = true
308
+ }
309
+ }
310
+ else if (originValue !== currentValue) {
311
+ ob[`${field}__diffable`] = true
312
+ }
313
+ }
314
+ return ob
315
+ }, {})
316
+ return {
317
+ ...originRow,
318
+ ...diffData,
319
+ isDiff: Object.keys(diffData).length > 0,
320
+ diffable: true,
321
+ operationType: 'U',
322
+ operateType: `${isCorrecte.value ? '修正' : '变更'}前`,
323
+ }
324
+ }).filter(originRow => originRow.isDiff)
325
+ if (originRows.length) {
326
+ updateOb[row[rowId]] = originRows
327
+ }
328
+ return updateOb
329
+ }, {})
330
+ newRows = data.reduce((rows, row) => {
331
+ if (['U'].includes(row.operationType)) {
332
+ if (updateRowsOb[row[rowId]] && updateRowsOb[row[rowId]].length) {
333
+ return rows.concat(row, ...updateRowsOb[row[rowId]])
334
+ }
335
+ }
336
+ else if (['D'].includes(row.operationType)) {
337
+ const deleteRow = deleteRows.find(item => item[rowId] === row[rowId])
338
+ return rows.concat(deleteRow ?? row)
339
+ }
340
+ return rows.concat(row)
341
+ }, [])
342
+ }
343
+ else {
344
+ newRows = data.map((row) => {
345
+ if (['D'].includes(row.operationType)) {
346
+ const deleteRow = deleteRows.find(item => item[rowId] === row[rowId])
347
+ if (deleteRow) {
348
+ return deleteRow
349
+ }
350
+ }
351
+ return row
352
+ })
353
+ }
354
+ console.log('newRows', newRows)
355
+ if (newRows && newRows.length) {
356
+ setTimeout(() => {
357
+ nextTick(() => {
358
+ const $grid = xGrid.value?.getGridInstance()
359
+ if ($grid) {
360
+ $grid.loadData(newRows.map((row) => {
361
+ return {
362
+ ...row,
363
+ checkbox: `${row.operationType}-${row[rowId]}`,
364
+ }
365
+ }))
366
+ }
367
+ loading.value = false
368
+ })
369
+ }, 100)
370
+ return
371
+ }
372
+ }
373
+ catch {
374
+
375
+ }
376
+ }
377
+ loading.value = false
378
+ }
379
+
380
+ function afterLoad({ data }) {
381
+ if (!detailInfo.value[getId('pcContractMainId')]) {
382
+ return
383
+ }
384
+ if (diffable.value) {
385
+ getDiffData(data, 'pcContractGoodsId')
386
+ }
387
+ if (isInit.value) {
388
+ return
389
+ }
390
+ nextTick(async () => {
391
+ try {
392
+ await saveDetail({
393
+ priceTaxFlag: isPriceTax.value,
394
+ }, false)
395
+ const detailData = await fetchDetailInfo({
396
+ id: detailInfo.value[getId('pcContractMainId')],
397
+ }, false)
398
+ const newData = (detailData && detailData[0]) || {}
399
+ console.log('newDetailInfo', newData)
400
+ updateDetailInfo(newData)
401
+ baseModule.value?.updateFormData?.({
402
+ contractAmount: newData.contractAmount || 0,
403
+ contractAmountTax: newData.contractAmountTax || 0,
404
+ contractAmountNoTax: newData.contractAmountNoTax || 0,
405
+ responsibilityCategoryLCode: newData.responsibilityCategoryLCode || '',
406
+ responsibilityCategoryLName: newData.responsibilityCategoryLName || '',
407
+ responsibilityCategoryMCode: newData.responsibilityCategoryMCode || '',
408
+ responsibilityCategoryMName: newData.responsibilityCategoryMName || '',
409
+ responsibilityCategorySCode: newData.responsibilityCategorySCode || '',
410
+ responsibilityCategorySName: newData.responsibilityCategorySName || '',
411
+ contractStartDate: newData.contractStartDate || '',
412
+ contractEndDate: newData.contractEndDate || '',
413
+ })
414
+ }
415
+ catch {
416
+
417
+ }
418
+ })
419
+ }
420
+
421
+ const gridEvents = reactive({
422
+ toolbarButtonClick: ({ code, $grid }) => {
423
+ switch (code) {
424
+ case 'ADD_CONTRACT_GOODS':
425
+ handleAdd()
426
+ break
427
+ case 'COPY_GOODS':
428
+ handleCopy($grid)
429
+ break
430
+ case 'DELETE_GOODS':
431
+ handleDelete($grid)
432
+ break
433
+ case 'VIEW_DETAIL':
434
+ handleViewDetail()
435
+ break
436
+ case 'VIEW_TEXT':
437
+ handleViewText()
438
+ break
439
+ }
440
+ },
441
+ })
442
+
443
+ const { openDialog } = useDialog()
444
+
445
+ // 新增操作
446
+ async function handleAdd() {
447
+ if (!detailInfo.value[getId('pcContractMainId')]) {
448
+ return ElMessage.warning('请先保存合同信息!')
449
+ }
450
+ try {
451
+ await priceModule.value.validateField('priceTaxFlag')
452
+ openDialog(PMPC9701, {
453
+ title: '商品明细',
454
+ pageId: 'PMPC9701',
455
+ componentParam: {
456
+ baseInfo: baseModuleFormData.value,
457
+ editable: editable.value,
458
+ diffable: diffable.value,
459
+ otherInfo: {
460
+ standardFlag: standardFlag.value,
461
+ businessType: businessType.value,
462
+ contractType: contractType.value,
463
+ isCorrecte: isCorrecte.value,
464
+ isCorrecteOrChange: isCorrecteOrChange.value,
465
+ isFirstVersion: isFirstVersion.value,
466
+ foreignFlag: foreignFlag.value,
467
+ },
468
+ data: {
469
+ pcContractMainId: detailInfo.value.pcContractMainId,
470
+ [getId('pcContractMainId')]: detailInfo.value[getId('pcContractMainId')],
471
+ isPriceTax: isPriceTax.value,
472
+ },
473
+ refresh,
474
+ getId,
475
+ },
476
+ })
477
+ }
478
+ catch {
479
+
480
+ }
481
+ }
482
+
483
+ // 复制
484
+ async function handleCopy($grid) {
485
+ return ElMessage.warning('该功能正在开发中!')
486
+ if (!detailInfo.value[getId('pcContractMainId')]) {
487
+ return ElMessage.warning('请先保存合同信息!')
488
+ }
489
+ const checkboxRecords = $grid.getCheckboxRecords()
490
+ if (!checkboxRecords.length) {
491
+ ElMessage.warning(`请选中一条数据`)
492
+ return
493
+ }
494
+ try {
495
+ await sendService({
496
+ serviceName: 'PMPC0101',
497
+ methodName: 'copyContractGoods',
498
+ eiBlocks: [
499
+ createEiBlock(checkboxRecords.map((item) => {
500
+ return {
501
+ [getId('pcContractMainId')]: detailInfo.value[getId('pcContractMainId')],
502
+ [getId('pcContractGoodsId')]: item[getId('pcContractGoodsId')],
503
+ }
504
+ }), 'result_2'),
505
+ ],
506
+ })
507
+ ElMessage.success('复制成功')
508
+ refresh()
509
+ }
510
+ catch {
511
+
512
+ }
513
+ }
514
+
515
+ // 删除
516
+ async function handleDelete($grid) {
517
+ if (!detailInfo.value[getId('pcContractMainId')]) {
518
+ return ElMessage.warning('请先保存合同信息!')
519
+ }
520
+ const checkboxRecords = $grid.getCheckboxRecords()
521
+ if (!checkboxRecords.length) {
522
+ ElMessage.warning(`请选中一条数据`)
523
+ return
524
+ }
525
+ try {
526
+ await ElMessageBox.confirm(`确定要删除吗?`)
527
+ const rows = checkboxRecords.filter((row) => {
528
+ return !isEmpty(row[getId('pcContractGoodsId')])
529
+ })
530
+ if (rows.length) {
531
+ await sendService({
532
+ serviceName: isCorrecteOrChange.value ? 'PMPC0102' : 'PMPC0101',
533
+ methodName: 'deleteContractGoods',
534
+ eiBlocks: [
535
+ createEiBlock(rows.map((item) => {
536
+ return {
537
+ pcContractMainId: detailInfo.value.pcContractMainId,
538
+ [getId('pcContractMainId')]: detailInfo.value[getId('pcContractMainId')],
539
+ pcContractGoodsId: item.pcContractGoodsId,
540
+ [getId('pcContractGoodsId')]: item[getId('pcContractGoodsId')],
541
+ }
542
+ }), 'result_2'),
543
+ ],
544
+ })
545
+ ElMessage.success('删除成功')
546
+ refresh()
547
+ }
548
+ else {
549
+ $grid.removeCheckboxRow()
550
+ }
551
+ }
552
+ catch {
553
+
554
+ }
555
+ }
556
+
557
+ // 编辑
558
+ async function handleEdit(row) {
559
+ try {
560
+ if (isApprovePage.value) {
561
+ return
562
+ }
563
+ await priceModule.value.validateField('priceTaxFlag')
564
+ const data = await sendService({
565
+ serviceName: 'PMPC9701',
566
+ methodName: isCorrecteOrChange.value ? 'detailForCompare' : 'detail',
567
+ eiBlocks: [
568
+ createEiBlock({
569
+ [getId('pcContractMainId')]: detailInfo.value[getId('pcContractMainId')],
570
+ pcContractGoodsId: row.pcContractGoodsId,
571
+ [getId('pcContractGoodsId')]: row[getId('pcContractGoodsId')],
572
+ businessType: businessType.value,
573
+ }, 'inqu_status'),
574
+ ],
575
+ blockName: 'inqu_status,inqu_status2',
576
+ })
577
+ const rowData = data && (data as any).inqu_status
578
+ const newData = (rowData && rowData[0]) || {}
579
+ if (isPriceTax.value === 'Y') {
580
+ newData.priceTax = newData.priceWithtax
581
+ }
582
+ else if (isPriceTax.value === 'N') {
583
+ newData.priceTax = newData.priceNotax
584
+ }
585
+ if (!isEmpty(newData.deliveryStartDate) || !isEmpty(newData.deliveryEndDate)) {
586
+ newData.deliveryDate = `${newData.deliveryStartDate || '/'} 至 ${newData.deliveryEndDate || '/'}`
587
+ }
588
+ const categoryData = await sendService({
589
+ serviceName: 'CMCG9904',
590
+ methodName: 'query',
591
+ eiBlocks: [
592
+ createEiBlock({
593
+ cgItemCode: newData.categoryCode,
594
+ }, 'inqu4_status'),
595
+ ],
596
+ blockName: 'result4',
597
+ })
598
+ console.log('categoryData', categoryData)
599
+ const categoryInfo = (categoryData && categoryData[0]) || {}
600
+ newData.categorySegment1 = categoryInfo.categorySegment1
601
+ console.log('newData', newData)
602
+ const diffInfo = ref({}) as any
603
+ if (diffable.value) {
604
+ const diffData = data && (data as any).inqu_status2
605
+ const diffObj = (diffData && diffData[0]) || {}
606
+ if (isPriceTax.value === 'Y') {
607
+ diffObj.priceTax = diffObj.priceWithtax
608
+ }
609
+ else if (isPriceTax.value === 'N') {
610
+ diffObj.priceTax = diffObj.priceNotax
611
+ }
612
+ if (!isEmpty(diffObj.deliveryStartDate) || !isEmpty(diffObj.deliveryEndDate)) {
613
+ const deliveryStartDate = diffObj.deliveryStartDate || newData.deliveryStartDate
614
+ const deliveryEndDate = diffObj.deliveryEndDate || newData.deliveryEndDate
615
+ diffObj.deliveryDate = `${deliveryStartDate ? dayjs(deliveryStartDate).format('YYYY-MM-DD') : '/'} 至 ${deliveryEndDate ? dayjs(deliveryEndDate).format('YYYY-MM-DD') : '/'}`
616
+ }
617
+ console.log('diffObj', diffObj)
618
+ diffInfo.value = compareData(diffObj, newData)
619
+ console.log('compareInfo', diffInfo.value)
620
+ }
621
+ openDialog(PMPC9701, {
622
+ title: '商品信息',
623
+ pageId: 'PMPC9701',
624
+ componentParam: {
625
+ baseInfo: baseModuleFormData.value,
626
+ editable: editable.value && !(diffable.value && row.diffable),
627
+ diffable: diffable.value,
628
+ editMode: 'edit',
629
+ otherInfo: {
630
+ standardFlag: standardFlag.value,
631
+ businessType: businessType.value,
632
+ contractType: contractType.value,
633
+ isCorrecte: isCorrecte.value,
634
+ isCorrecteOrChange: isCorrecteOrChange.value,
635
+ isFirstVersion: isFirstVersion.value,
636
+ foreignFlag: foreignFlag.value,
637
+ hedgingFlag: hedgingFlag.value && !isCorrecteOrChange.value,
638
+ },
639
+ data: {
640
+ ...newData,
641
+ pcContractMainId: detailInfo.value.pcContractMainId,
642
+ [getId('pcContractMainId')]: detailInfo.value[getId('pcContractMainId')],
643
+ isPriceTax: isPriceTax.value,
644
+ },
645
+ diff: diffInfo.value,
646
+ refresh,
647
+ getId,
648
+ },
649
+ })
650
+ }
651
+ catch {
652
+
653
+ }
654
+ }
655
+
656
+ // 价格公式
657
+ function handleFormulaInfo(row) {
658
+ if (isApprovePage.value) {
659
+ return
660
+ }
661
+ const param = {
662
+ jrInstanceMainId: row.brPriceInstanceHeadId,
663
+ targetJrInstanceMainId: row.oldBrPriceInstanceHeadId,
664
+ disabled: !editable.value,
665
+ isCorrecteOrChange: isCorrecteOrChange.value,
666
+ } as any
667
+ if (!param.disabled) {
668
+ const flag = ref(false)
669
+ if (isCorrecteOrChange.value) {
670
+ flag.value = isEmpty(row.oldBrPriceInstanceHeadId) || (row.brPriceInstanceHeadId === row.oldBrPriceInstanceHeadId)
671
+ }
672
+ if (flag.value) {
673
+ param.newJrInstanceMainId = generateId()
674
+ param.updateFn = async (updateInfo) => {
675
+ if (isCorrecteOrChange.value) {
676
+ const res = await sendService({
677
+ serviceName: 'JMJR02',
678
+ methodName: 'detail',
679
+ loading: false,
680
+ eiBlocks: [
681
+ createEiBlock({
682
+ jrInstanceMainId: param.newJrInstanceMainId,
683
+ }, 'inqu_status'),
684
+ ],
685
+ blockName: true,
686
+ }) as any
687
+ const detailData = res.get('result') ?? (res.getBlock('result')?.getMappedRows() || [])
688
+ console.log('JMJR02.detailData', detailData)
689
+ const detailObj = (detailData && detailData[0]) || {}
690
+ await sendService({
691
+ serviceName: 'PMPC9701',
692
+ methodName: 'updateContractGoodsPriceFormula',
693
+ loading: false,
694
+ eiBlocks: [
695
+ createEiBlock({
696
+ brPriceInstanceHeadId: param.newJrInstanceMainId,
697
+ priceInstanceHeadCode: detailObj.formulaCode,
698
+ [getId('pcContractGoodsId')]: row[getId('pcContractGoodsId')],
699
+ }, 'inqu_status'),
700
+ ],
701
+ })
702
+ updateInfo({
703
+ newJrInstanceMainId: '',
704
+ jrInstanceMainId: param.newJrInstanceMainId,
705
+ targetJrInstanceMainId: row.brPriceInstanceHeadId,
706
+ })
707
+ refresh()
708
+ }
709
+ return Promise.resolve(true)
710
+ }
711
+ }
712
+ }
713
+ openDialog(JMJR0101, {
714
+ title: '价格公式详情',
715
+ componentParam: {
716
+ ...param,
717
+ },
718
+ })
719
+ }
720
+
721
+ // 查看合同详情
722
+ function handleViewDetail() {
723
+ const path = [`/web/${isHistory.value ? 'PMPC0102' : 'PMPC0101'}`, decodeURIComponent(Qs.stringify({
724
+ [getId('pcContractMainId')]: detailInfo.value[getId('pcContractMainId')],
725
+ businessType: businessType.value,
726
+ }))].join('?')
727
+ if (import.meta.env.VITE_USER_NODE_ENV === 'development') {
728
+ openV6Page(`${window.location.origin}${window.location.pathname}#${path}`)
729
+ }
730
+ else {
731
+ openV6Page(`${import.meta.env.VITE_GRIC_URL}/baseVue/index.html#${path}`)
732
+ }
733
+ }
734
+
735
+ const { openFileBFSS0001 } = useFileUpload()
736
+
737
+ // 查看合同文本
738
+ function handleViewText() {
739
+ const bizTypeCode = 'PM_CONTRACT_PROPOSE,PM_CONTRACT_FORMAL,PM_CONTRACT_CORRECT,PM_CONTRACT_END'
740
+ const flag = 'show'
741
+ const bizBillId = detailInfo.value.pcContractMainId
742
+ const bizBillCode = detailInfo.value.pcContractCode
743
+ const bizBillVersion = detailInfo.value.contractVersion
744
+ const bookId = detailInfo.value.bookId
745
+ const verFlag = 'N'
746
+ const fileTypeCode = ''
747
+ openFileBFSS0001({
748
+ bizTypeCode,
749
+ contractId: bizBillId,
750
+ bizBillId,
751
+ bizBillCode,
752
+ bizBillVersion,
753
+ fileTypeCode,
754
+ flag,
755
+ bookId,
756
+ verFlag,
757
+ editable: false,
758
+ data: detailInfo.value,
759
+ })
760
+ }
761
+
762
+ watch([
763
+ () => isApprovePage.value,
764
+ () => editable.value,
765
+ () => hedgingFlag.value,
766
+ ], () => {
767
+ nextTick(() => {
768
+ xGrid.value.btnSetVisible(['ADD_CONTRACT_GOODS', 'COPY_GOODS', 'DELETE_GOODS'], !isApprovePage.value)
769
+ xGrid.value.btnSetVisible(['VIEW_DETAIL', 'VIEW_TEXT'], isApprovePage.value)
770
+ xGrid.value.btnSetDisable(['COPY_GOODS'], !editable.value)
771
+ if (!isCorrecteOrChange.value) {
772
+ xGrid.value.btnSetDisable(['ADD_CONTRACT_GOODS', 'DELETE_GOODS'], editable.value ? hedgingFlag.value : true)
773
+ }
774
+ else {
775
+ xGrid.value.btnSetDisable(['ADD_CONTRACT_GOODS', 'DELETE_GOODS'], !editable.value)
776
+ }
777
+ })
778
+ }, {
779
+ immediate: true,
780
+ })
781
+
782
+ defineExpose({
783
+ reload,
784
+ validator: handleValidator,
785
+ getTableData,
786
+ scrollIntoTop,
787
+ })
788
+ </script>
789
+
790
+ <style scoped></style>