arms-app 1.0.74 → 1.0.76

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 (3) hide show
  1. package/package.json +1 -1
  2. package/view/1.d +87 -373
  3. package/view/2.d +0 -529
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arms-app",
3
- "version": "1.0.74",
3
+ "version": "1.0.76",
4
4
  "description": "一个基于 Express 的 Web 应用1",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/view/1.d CHANGED
@@ -1,391 +1,105 @@
1
1
  <template>
2
- <section class="visit-records-page">
3
- <h1>拜访记录</h1>
4
- <el-form :model="form" label-position="top" size="mini" class="visit-filter-form">
5
- <el-row :gutter="16" type="flex" align="bottom">
6
- <el-col :span="6">
7
- <el-form-item label="拜访记录类型">
8
- <el-select v-model="form.type" placeholder="拜访记录" clearable style="width: 100%">
9
- <el-option v-for="opt in typeOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
10
- </el-select>
11
- </el-form-item>
12
- </el-col>
13
- <el-col :span="6">
14
- <el-form-item label="拜访记录日期">
15
- <el-date-picker
16
- v-model="form.startDate"
17
- type="date"
18
- placeholder="开始日期"
19
- value-format="yyyy-MM-dd"
20
- clearable
21
- style="width: 100%"
22
- />
23
- </el-form-item>
24
- </el-col>
25
- <el-col :span="6">
26
- <el-form-item label=" ">
27
- <el-date-picker
28
- v-model="form.endDate"
29
- type="date"
30
- placeholder="结束日期"
31
- value-format="yyyy-MM-dd"
32
- clearable
33
- style="width: 100%"
34
- />
35
- </el-form-item>
36
- </el-col>
37
- <el-col :span="6">
38
- <el-form-item label=" ">
39
- <div class="ops">
40
- <el-button type="primary" size="mini" @click="onSearch">查询</el-button>
41
- <el-button size="mini" @click="onReset">重置</el-button>
42
- </div>
43
- </el-form-item>
44
- </el-col>
45
- </el-row>
46
- </el-form>
2
+ <el-dialog
3
+ :title="title"
4
+ :visible.sync="innerVisible"
5
+ :close-on-click-modal="false"
6
+ @closed="onClosed"
7
+ >
8
+ <el-form
9
+ ref="form"
10
+ :model="form"
11
+ :rules="rules"
12
+ label-width="90px"
13
+ >
14
+ <el-form-item label="姓名" prop="name">
15
+ <el-input v-model="form.name" />
16
+ </el-form-item>
47
17
 
48
- <div class="toolbar">
49
- <el-button type="warning" size="mini" @click="onAddRecord">新增拜访记录</el-button>
50
- </div>
18
+ <el-form-item label="邮箱" prop="email">
19
+ <el-input v-model="form.email" />
20
+ </el-form-item>
21
+ </el-form>
51
22
 
52
- <el-collapse v-model="activeNames" class="visit-collapse">
53
- <el-collapse-item
54
- v-for="item in displayedRecords"
55
- :key="item.id"
56
- :name="item.id"
57
- >
58
- <template slot="title">
59
- {{ item.title }}
60
- </template>
61
- <div class="visit-content">
62
- <el-form :model="item" label-width="90px" size="mini" class="visit-detail-form">
63
- <el-row :gutter="16">
64
- <el-col :span="8">
65
- <el-form-item label="拜访形式">
66
- <el-input v-model="item.visitMode" :disabled="!item.isNew" />
67
- </el-form-item>
68
- </el-col>
69
- <el-col :span="8">
70
- <el-form-item label="拜访时间">
71
- <el-input v-model="item.visitTime" :disabled="!item.isNew" />
72
- </el-form-item>
73
- </el-col>
74
- </el-row>
75
- <el-row :gutter="16">
76
- <el-col :span="16">
77
- <el-form-item label="拜访地点">
78
- <el-input v-model="item.address" :disabled="!item.isNew" />
79
- </el-form-item>
80
- </el-col>
81
- </el-row>
82
- <el-row :gutter="16">
83
- <el-col :span="8">
84
- <el-form-item label="被拜访人">
85
- <el-input v-model="item.visitedPerson" :disabled="!item.isNew" />
86
- </el-form-item>
87
- </el-col>
88
- <el-col :span="8">
89
- <el-form-item label="被拜访人职务">
90
- <el-input v-model="item.visitedPosition" :disabled="!item.isNew" />
91
- </el-form-item>
92
- </el-col>
93
- </el-row>
94
- <el-row :gutter="16">
95
- <el-col :span="8">
96
- <el-form-item label="被拜访人联系方式">
97
- <el-input v-model="item.contactWay" :disabled="!item.isNew" />
98
- </el-form-item>
99
- </el-col>
100
- <el-col :span="8">
101
- <el-form-item label="拜访结果">
102
- <el-input v-model="item.result" :disabled="!item.isNew" />
103
- </el-form-item>
104
- </el-col>
105
- </el-row>
106
- <el-row :gutter="16">
107
- <el-col :span="16">
108
- <el-form-item label="协同人员">
109
- <el-input v-model="item.partners" :disabled="!item.isNew" />
110
- </el-form-item>
111
- </el-col>
112
- </el-row>
113
- <el-row :gutter="16">
114
- <el-col :span="16">
115
- <el-form-item label="拜访内容">
116
- <el-input
117
- type="textarea"
118
- :rows="3"
119
- v-model="item.content"
120
- :disabled="!item.isNew"
121
- />
122
- </el-form-item>
123
- </el-col>
124
- </el-row>
125
- <el-row :gutter="16">
126
- <el-col :span="16">
127
- <el-form-item label="客户诉求">
128
- <el-input
129
- type="textarea"
130
- :rows="3"
131
- v-model="item.customerDemand"
132
- :disabled="!item.isNew"
133
- />
134
- </el-form-item>
135
- </el-col>
136
- </el-row>
137
- <el-row :gutter="16">
138
- <el-col :span="16">
139
- <el-form-item label="影像资料">
140
- <div class="image-list">
141
- <div
142
- v-for="(img, idx) in item.images"
143
- :key="idx"
144
- class="image-item"
145
- >
146
- <i class="el-icon-view"></i>
147
- </div>
148
- </div>
149
- </el-form-item>
150
- </el-col>
151
- </el-row>
152
- </el-form>
153
- </div>
154
- </el-collapse-item>
155
- </el-collapse>
156
- </section>
23
+ <span slot="footer">
24
+ <el-button @click="innerVisible = false">取消</el-button>
25
+ <el-button type="primary" :loading="submitting" @click="submit">确定</el-button>
26
+ </span>
27
+ </el-dialog>
157
28
  </template>
158
29
 
159
30
  <script>
160
31
  export default {
161
- name: "VisitRecordsView",
32
+ name: "FormDialog",
33
+ props: {
34
+ // 父组件 v-model
35
+ value: { type: Boolean, default: false },
36
+ title: { type: String, default: "表单" },
37
+
38
+ // 初始数据(编辑时传 row)
39
+ initialData: { type: Object, default: () => ({}) }
40
+ },
162
41
  data() {
163
- const records = [
164
- {
165
- id: "1",
166
- type: "record",
167
- date: "2025-09-24",
168
- location: "拜访地点",
169
- purpose: "拜访目的",
170
- visitMode: "现场拜访",
171
- visitTime: "2025-12-12 16:00:00",
172
- address: "北京市xxxx路xxxx街道xxxxxxxx号",
173
- visitedPerson: "张三",
174
- visitedPosition: "总经理",
175
- contactWay: "张三",
176
- result: "已触达目标业务意向",
177
- partners: "人员A,人员B,人员C,人员D,人员E,人员F",
178
- content: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
179
- customerDemand: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
180
- images: [1, 2, 3],
181
- },
182
- {
183
- id: "2",
184
- type: "record",
185
- date: "2025-09-24",
186
- location: "拜访地点",
187
- purpose: "拜访目的",
188
- visitMode: "现场拜访",
189
- visitTime: "2025-12-12 16:00:00",
190
- address: "北京市xxxx路xxxx街道xxxxxxxx号",
191
- visitedPerson: "张三",
192
- visitedPosition: "总经理",
193
- contactWay: "张三",
194
- result: "已触达目标业务意向",
195
- partners: "人员A,人员B,人员C,人员D,人员E,人员F",
196
- content: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
197
- customerDemand: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
198
- images: [1, 2, 3],
199
- },
200
- {
201
- id: "3",
202
- type: "record",
203
- date: "2025-09-24",
204
- location: "拜访地点",
205
- purpose: "拜访目的",
206
- visitMode: "现场拜访",
207
- visitTime: "2025-12-12 16:00:00",
208
- address: "北京市xxxx路xxxx街道xxxxxxxx号",
209
- visitedPerson: "张三",
210
- visitedPosition: "总经理",
211
- contactWay: "张三",
212
- result: "已触达目标业务意向",
213
- partners: "人员A,人员B,人员C,人员D,人员E,人员F",
214
- content: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
215
- customerDemand: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
216
- images: [1, 2, 3],
217
- },
218
- {
219
- id: "4",
220
- type: "record",
221
- date: "2025-09-24",
222
- location: "拜访地点",
223
- purpose: "拜访目的",
224
- visitMode: "现场拜访",
225
- visitTime: "2025-12-12 16:00:00",
226
- address: "北京市xxxx路xxxx街道xxxxxxxx号",
227
- visitedPerson: "张三",
228
- visitedPosition: "总经理",
229
- contactWay: "张三",
230
- result: "已触达目标业务意向",
231
- partners: "人员A,人员B,人员C,人员D,人员E,人员F",
232
- content: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
233
- customerDemand: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
234
- images: [1, 2, 3],
235
- },
236
- {
237
- id: "5",
238
- type: "record",
239
- date: "2025-09-24",
240
- location: "北京市顺义区北京银行行研发展中心_智拓系统",
241
- purpose: "拜访目的",
242
- visitMode: "现场拜访",
243
- visitTime: "2025-12-12 16:00:00",
244
- address: "北京市顺义区北京银行行研发展中心_智拓系统",
245
- visitedPerson: "张三",
246
- visitedPosition: "总经理",
247
- contactWay: "张三",
248
- result: "已触达目标业务意向",
249
- partners: "人员A,人员B,人员C,人员D,人员E,人员F",
250
- content: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
251
- customerDemand: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
252
- images: [1, 2, 3],
253
- },
254
- {
255
- id: "6",
256
- type: "record",
257
- date: "2025-09-24",
258
- location: "拜访地点",
259
- purpose: "拜访目的",
260
- visitMode: "现场拜访",
261
- visitTime: "2025-12-12 16:00:00",
262
- address: "北京市xxxx路xxxx街道xxxxxxxx号",
263
- visitedPerson: "张三",
264
- visitedPosition: "总经理",
265
- contactWay: "张三",
266
- result: "已触达目标业务意向",
267
- partners: "人员A,人员B,人员C,人员D,人员E,人员F",
268
- content: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
269
- customerDemand: "文案文案文案文案文案文案文案文案文案文案文案文案文案文案文案",
270
- images: [1, 2, 3],
271
- },
272
- ];
273
42
  return {
274
- form: {
275
- type: "",
276
- startDate: "",
277
- endDate: "",
278
- },
279
- typeOptions: [
280
- { label: "拜访记录", value: "record" },
281
- ],
282
- records,
283
- filteredRecords: records,
284
- activeNames: ["1"],
43
+ innerVisible: false,
44
+ submitting: false,
45
+ form: { name: "", email: "" },
46
+ rules: {
47
+ name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
48
+ email: [
49
+ { required: true, message: "请输入邮箱", trigger: "blur" },
50
+ { type: "email", message: "邮箱格式不正确", trigger: "blur" }
51
+ ]
52
+ }
285
53
  };
286
54
  },
287
- computed: {
288
- displayedRecords() {
289
- return this.filteredRecords.map((item) => {
290
- const hasBasic = item.date || item.location || item.purpose;
291
- const title = hasBasic
292
- ? `拜访记录(${item.date}_${item.location}_${item.purpose})`
293
- : "新增拜访记录";
294
- return {
295
- ...item,
296
- title,
297
- };
298
- });
55
+ watch: {
56
+ // 父 -> 子
57
+ value: {
58
+ immediate: true,
59
+ handler(v) {
60
+ this.innerVisible = v;
61
+ if (v) this.resetFromInitial();
62
+ }
299
63
  },
64
+ // 子 -> 父(保证父组件状态同步)
65
+ innerVisible(v) {
66
+ this.$emit("input", v);
67
+ },
68
+ // 如果父组件换了 initialData,且弹窗开着,就刷新表单
69
+ initialData: {
70
+ deep: true,
71
+ handler() {
72
+ if (this.innerVisible) this.resetFromInitial();
73
+ }
74
+ }
300
75
  },
301
76
  methods: {
302
- onSearch() {
303
- const { type, startDate, endDate } = this.form;
304
- this.filteredRecords = this.records.filter((item) => {
305
- if (type && item.type !== type) return false;
306
- if (startDate && item.date < startDate) return false;
307
- if (endDate && item.date > endDate) return false;
308
- return true;
77
+ resetFromInitial() {
78
+ const base = { name: "", email: "" };
79
+ this.form = Object.assign({}, base, this.initialData);
80
+ this.$nextTick(() => {
81
+ this.$refs.form && this.$refs.form.clearValidate();
309
82
  });
310
- if (this.filteredRecords.length) {
311
- this.activeNames = [this.filteredRecords[0].id];
312
- }
313
- },
314
- onReset() {
315
- this.form.type = "";
316
- this.form.startDate = "";
317
- this.form.endDate = "";
318
- this.filteredRecords = this.records.slice();
319
- this.activeNames = this.filteredRecords.length ? [this.filteredRecords[0].id] : [];
320
83
  },
321
- onAddRecord() {
322
- const id = String(Date.now());
323
- const empty = {
324
- id,
325
- type: "record",
326
- isNew: true,
327
- date: "",
328
- location: "",
329
- purpose: "",
330
- visitMode: "",
331
- visitTime: "",
332
- address: "",
333
- visitedPerson: "",
334
- visitedPosition: "",
335
- contactWay: "",
336
- result: "",
337
- partners: "",
338
- content: "",
339
- customerDemand: "",
340
- images: [],
341
- };
342
- this.records = [empty].concat(this.records);
343
- this.filteredRecords = [empty].concat(this.filteredRecords);
344
- this.activeNames = [id];
84
+
85
+ onClosed() {
86
+ // 关掉后清理,避免下次打开残留
87
+ this.resetFromInitial();
88
+ this.$emit("closed");
345
89
  },
346
- },
347
- };
348
- </script>
349
90
 
350
- <style scoped>
351
- .visit-records-page {
352
- padding: 24px;
353
- }
354
- .visit-filter-form :deep(.el-form-item) {
355
- margin-bottom: 12px;
356
- }
357
- .ops {
358
- display: flex;
359
- gap: 8px;
360
- }
361
- .toolbar {
362
- margin: 16px 0 8px;
363
- }
364
- .visit-collapse {
365
- border-top: none;
366
- }
367
- .visit-content {
368
- padding: 8px 16px;
369
- }
370
- .visit-detail-form :deep(.el-input__inner),
371
- .visit-detail-form :deep(.el-textarea__inner) {
372
- background-color: #f5f7fa;
373
- }
374
- .image-list {
375
- display: flex;
376
- gap: 12px;
377
- }
378
- .image-item {
379
- width: 120px;
380
- height: 80px;
381
- background-color: #f5f7fa;
382
- border-radius: 4px;
383
- display: flex;
384
- align-items: center;
385
- justify-content: center;
386
- color: #909399;
387
- }
388
- .image-item i {
389
- font-size: 20px;
390
- }
391
- </style>
91
+ submit() {
92
+ this.$refs.form.validate((valid) => {
93
+ if (!valid) return;
94
+ this.submitting = true;
95
+
96
+ // 把数据交给父组件处理;父组件成功后调用 done() 关闭
97
+ const done = () => (this.innerVisible = false);
98
+ this.$emit("submit", { ...this.form }, done);
99
+
100
+ this.submitting = false;
101
+ });
102
+ }
103
+ }
104
+ };
105
+ </script>
package/view/2.d DELETED
@@ -1,529 +0,0 @@
1
- <template>
2
- <section class="medal-settings-page">
3
- <h1>勋章设置</h1>
4
- <p class="desc">展示勋章基础信息,可查看启用状态与基本配置。</p>
5
-
6
- <div class="toolbar">
7
- <el-button type="primary" size="mini" @click="onOpenCreate">
8
- 新增
9
- </el-button>
10
- </div>
11
-
12
- <el-dialog
13
- title="创建"
14
- :visible.sync="dialogVisible"
15
- width="720px"
16
- :close-on-click-modal="false"
17
- >
18
- <el-form :model="formMedal" label-width="90px" size="small" class="create-form">
19
- <el-form-item label="授予主体">
20
- <el-select v-model="formMedal.confeSubKno" placeholder="请选择授予主体">
21
- <el-option
22
- v-for="opt in subjectOptions"
23
- :key="opt.value"
24
- :label="opt.label"
25
- :value="opt.value"
26
- />
27
- </el-select>
28
- </el-form-item>
29
- <el-form-item label="勋章名称">
30
- <el-input v-model="formMedal.medalName" placeholder="请输入勋章名称" />
31
- </el-form-item>
32
- <el-form-item label="授予方式">
33
- <el-input :value="formatConfeMode('4')" disabled />
34
- </el-form-item>
35
- <el-form-item label="是否限时">
36
- <el-select v-model="formMedal.limitTmFlag" placeholder="请选择">
37
- <el-option
38
- v-for="opt in limitTimeOptions"
39
- :key="opt.value"
40
- :label="opt.label"
41
- :value="opt.value"
42
- />
43
- </el-select>
44
- </el-form-item>
45
- <el-form-item v-if="formMedal.limitTmFlag === 'Y'" label="限时时长">
46
- <div class="inline-group">
47
- <el-input-number v-model="formMedal.wearDurat" :min="1" />
48
- <el-select v-model="formMedal.tmUnitType" style="margin-left: 8px; width: 120px">
49
- <el-option
50
- v-for="opt in tmUnitOptions"
51
- :key="opt.value"
52
- :label="opt.label"
53
- :value="opt.value"
54
- />
55
- </el-select>
56
- </div>
57
- </el-form-item>
58
- <el-form-item label="是否限量">
59
- <el-select v-model="formMedal.limitQtyFlag" placeholder="请选择">
60
- <el-option
61
- v-for="opt in limitQtyOptions"
62
- :key="opt.value"
63
- :label="opt.label"
64
- :value="opt.value"
65
- />
66
- </el-select>
67
- </el-form-item>
68
- <el-form-item v-if="formMedal.limitQtyFlag === 'Y'" label="勋章数量">
69
- <el-input-number v-model="formMedal.medalQty" :min="1" />
70
- </el-form-item>
71
- <el-form-item label="勋章描述">
72
- <el-input
73
- type="textarea"
74
- v-model="formMedal.medalDesc"
75
- :rows="3"
76
- maxlength="150"
77
- show-word-limit
78
- placeholder="请输入勋章描述"
79
- />
80
- </el-form-item>
81
- <div class="upload-block">
82
- <div class="upload-label">
83
- 静态勋章
84
- </div>
85
- <div class="upload-content">
86
- <el-upload
87
- class="avatar-uploader"
88
- action="#"
89
- :auto-upload="false"
90
- :show-file-list="false"
91
- :before-upload="onBeforeUpload"
92
- >
93
- <el-button size="small" type="primary">选择图片</el-button>
94
- <div slot="tip" class="upload-tip">
95
- 支持上传 PNG、JPG、JPEG 格式文件,文件大小小于 10M
96
- </div>
97
- </el-upload>
98
- </div>
99
- </div>
100
- </el-form>
101
- <span slot="footer" class="dialog-footer">
102
- <el-button size="small" @click="dialogVisible = false">取消</el-button>
103
- <el-button size="small" type="primary" @click="onSave">
104
- 保存
105
- </el-button>
106
- </span>
107
- </el-dialog>
108
-
109
- <el-table
110
- ref="medalTable"
111
- :key="tableKey"
112
- :data="rows"
113
- border
114
- stripe
115
- size="small"
116
- style="width: 100%"
117
- >
118
- <el-table-column
119
- v-for="col in columns"
120
- :key="col.key || col.prop"
121
- :prop="col.prop"
122
- :label="col.label"
123
- :width="col.width"
124
- :min-width="col.minWidth"
125
- :align="col.align || 'left'"
126
- :header-align="col.headerAlign || col.align || 'left'"
127
- :fixed="col.fixed"
128
- >
129
- <template slot="header">
130
- <div class="header-wrapper header-draggable">
131
- <span class="header-label">{{ col.label }}</span>
132
- </div>
133
- </template>
134
- <template slot-scope="scope">
135
- <span v-if="col.type === 'index'">
136
- {{ scope.$index + 1 }}
137
- </span>
138
- <div v-else-if="col.type === 'icon'" class="medal-icon">
139
- <img
140
- v-if="scope.row.filePicUrl"
141
- :src="scope.row.filePicUrl"
142
- alt=""
143
- />
144
- </div>
145
- <span v-else-if="col.type === 'confeMode'">
146
- {{ formatConfeMode(scope.row.confeMode) }}
147
- </span>
148
- <span v-else-if="col.type === 'limitTmFlag'">
149
- {{ scope.row.limitTmFlag === "Y" ? "限时" : "不限时" }}
150
- </span>
151
- <span v-else-if="col.type === 'wearDurat'">
152
- <span v-if="scope.row.limitTmFlag === 'Y'">
153
- {{ scope.row.wearDurat }}{{ formatTmUnit(scope.row.tmUnitType) }}
154
- </span>
155
- <span v-else>
156
- 不限期
157
- </span>
158
- </span>
159
- <span v-else-if="col.type === 'medalQty'">
160
- <span v-if="scope.row.limitQtyFlag === 'Y'">
161
- {{ scope.row.medalQty }}
162
- </span>
163
- <span v-else>
164
- 不限量
165
- </span>
166
- </span>
167
- <span v-else-if="col.type === 'createDate'">
168
- {{ formatDate(scope.row.createTm) }}
169
- </span>
170
- <span v-else-if="col.type === 'updateDate'">
171
- {{ formatDate(scope.row.updateTm) }}
172
- </span>
173
- <span v-else-if="col.type === 'switch'">
174
- <el-switch
175
- v-model="scope.row.activaFlag"
176
- active-value="Y"
177
- inactive-value="N"
178
- active-text="启用"
179
- inactive-text="停用"
180
- @change="onToggleActive(scope.row)"
181
- />
182
- </span>
183
- <span v-else-if="col.type === 'actions'">
184
- <el-button type="text" size="mini" @click="onPreview(scope.row)">
185
- 预览
186
- </el-button>
187
- <el-button type="text" size="mini" @click="onMore(scope.row)">
188
- 更多
189
- </el-button>
190
- </span>
191
- <span v-else>
192
- {{ scope.row[col.prop] }}
193
- </span>
194
- </template>
195
- </el-table-column>
196
- </el-table>
197
- </section>
198
- </template>
199
-
200
- <script>
201
- import Sortable from "sortablejs";
202
-
203
- export default {
204
- name: "MedalSettingsView",
205
- data() {
206
- const rows = [
207
- {
208
- id: 1,
209
- activaFlag: "Y",
210
- confeMode: "4",
211
- confeSubKno: "SORG",
212
- medalObjName: "授予客户经理",
213
- createTm: "2025-11-26T11:17:09.000Z",
214
- creatorNo: "046083",
215
- filePicUrl: "/getUrl?fileId=3d6457ca-3d05-463f-8acd-d5a56d773c40",
216
- limitQtyFlag: "Y",
217
- limitTmFlag: "Y",
218
- medalDesc: "",
219
- medalName: "阿萨德",
220
- medalNo: "SORG419ABFE1ADE9",
221
- medalQty: 999,
222
- issuedQty: 2,
223
- tmUnitType: "D",
224
- updateStaffNo: "046083",
225
- updateTm: "2025-12-30T13:10:44.000Z",
226
- wearDurat: 12
227
- },
228
- {
229
- id: 2,
230
- activaFlag: "Y",
231
- confeMode: "4",
232
- confeSubKno: "CU",
233
- medalObjName: "授予客户经理",
234
- createTm: "2025-11-26T11:17:09.000Z",
235
- creatorNo: "046083",
236
- filePicUrl: "/getUrl?fileId=7661069b-aeb9-450b-aa78-3192d53e4e10",
237
- limitQtyFlag: "N",
238
- limitTmFlag: "N",
239
- medalDesc: "",
240
- medalName: "1111",
241
- medalNo: "CU41990D4501B5",
242
- medalQty: 0,
243
- issuedQty: 0,
244
- tmUnitType: "",
245
- updateStaffNo: "046083",
246
- updateTm: "2025-12-30T13:10:44.000Z",
247
- wearDurat: 0
248
- },
249
- {
250
- id: 3,
251
- activaFlag: "N",
252
- confeMode: "4",
253
- confeSubKno: "CU",
254
- medalObjName: "授予客户经理",
255
- createTm: "2025-11-26T11:17:09.000Z",
256
- creatorNo: "046083",
257
- filePicUrl: "/getUrl?fileId=3d6457ca-3d05-463f-8acd-d5a56d773c40",
258
- limitQtyFlag: "Y",
259
- limitTmFlag: "Y",
260
- medalDesc: "",
261
- medalName: "测试勋章",
262
- medalNo: "CU419917C23D9C",
263
- medalQty: 999,
264
- issuedQty: 0,
265
- tmUnitType: "D",
266
- updateStaffNo: "046083",
267
- updateTm: "2025-11-26T11:10:44.000Z",
268
- wearDurat: 12
269
- }
270
- ];
271
- return {
272
- rows,
273
- columns: [
274
- { key: "index", label: "序号", width: 60, align: "center", type: "index" },
275
- { key: "medalNo", prop: "medalNo", label: "勋章编号", minWidth: 180 },
276
- { key: "icon", label: "勋章图标", width: 90, align: "center", type: "icon" },
277
- { key: "medalName", prop: "medalName", label: "勋章名称", minWidth: 140 },
278
- { key: "medalObjName", prop: "medalObjName", label: "勋章对象", minWidth: 140 },
279
- { key: "confeMode", prop: "confeMode", label: "发放方式", width: 120, align: "center", type: "confeMode" },
280
- { key: "limitTmFlag", prop: "limitTmFlag", label: "是否限时", width: 100, align: "center", type: "limitTmFlag" },
281
- { key: "wearDurat", prop: "wearDurat", label: "限时时长", width: 120, align: "center", type: "wearDurat" },
282
- { key: "medalQty", prop: "medalQty", label: "发放数量", width: 100, align: "center", type: "medalQty" },
283
- { key: "issuedQty", prop: "issuedQty", label: "已发数量", width: 100, align: "center" },
284
- { key: "createTm", prop: "createTm", label: "创建日期", width: 160, align: "center", type: "createDate" },
285
- { key: "updateTm", prop: "updateTm", label: "更新日期", width: 160, align: "center", type: "updateDate" },
286
- { key: "activaFlag", prop: "activaFlag", label: "启用/停用", width: 120, align: "center", type: "switch" },
287
- { key: "actions", label: "操作", width: 140, align: "center", fixed: "right", type: "actions" }
288
- ],
289
- headerSortable: null,
290
- tableKey: 0,
291
- isDestroyed: false,
292
- dialogVisible: false,
293
- formMedal: {
294
- confeSubKno: "CU",
295
- medalName: "",
296
- limitTmFlag: "N",
297
- limitQtyFlag: "N",
298
- wearDurat: 12,
299
- tmUnitType: "D",
300
- medalQty: 0,
301
- medalDesc: "",
302
- filePicUrl: ""
303
- },
304
- subjectOptions: [
305
- { label: "客户经理", value: "CU" }
306
- ],
307
- limitTimeOptions: [
308
- { label: "不限时", value: "N" },
309
- { label: "限时", value: "Y" }
310
- ],
311
- limitQtyOptions: [
312
- { label: "不限量", value: "N" },
313
- { label: "限量", value: "Y" }
314
- ],
315
- tmUnitOptions: [
316
- { label: "日", value: "D" },
317
- { label: "月", value: "M" },
318
- { label: "年", value: "Y" }
319
- ]
320
- };
321
- },
322
- mounted() {
323
- this.$nextTick(() => {
324
- this.initColumnDrag();
325
- });
326
- },
327
- beforeDestroy() {
328
- this.isDestroyed = true;
329
- if (this.headerSortable && this.headerSortable.destroy) {
330
- this.headerSortable.destroy();
331
- this.headerSortable = null;
332
- }
333
- },
334
- methods: {
335
- onOpenCreate() {
336
- this.resetForm();
337
- this.dialogVisible = true;
338
- },
339
- resetForm() {
340
- this.formMedal = {
341
- confeSubKno: "CU",
342
- medalName: "",
343
- limitTmFlag: "N",
344
- limitQtyFlag: "N",
345
- wearDurat: 12,
346
- tmUnitType: "D",
347
- medalQty: 0,
348
- medalDesc: "",
349
- filePicUrl: ""
350
- };
351
- },
352
- onBeforeUpload() {
353
- this.formMedal.filePicUrl = "";
354
- return false;
355
- },
356
- onSave() {
357
- const now = new Date().toISOString();
358
- const subject = this.subjectOptions.find(item => item.value === this.formMedal.confeSubKno);
359
- const params = {
360
- activaFlag: "Y",
361
- confeMode: "4",
362
- confeSubKno: this.formMedal.confeSubKno,
363
- createTm: now,
364
- creatorNo: "046083",
365
- fileGifName: "",
366
- fileGifSize: "",
367
- fileGifUrl: "",
368
- filePicName: "",
369
- filePicSize: "",
370
- filePicUrl: this.formMedal.filePicUrl || "",
371
- limitQtyFlag: this.formMedal.limitQtyFlag,
372
- limitTmFlag: this.formMedal.limitTmFlag,
373
- medalDesc: this.formMedal.medalDesc,
374
- medalName: this.formMedal.medalName,
375
- tmUnitType: this.formMedal.tmUnitType,
376
- updateStaffNo: "046083",
377
- updateTm: now,
378
- medalQty: this.formMedal.limitQtyFlag === "Y" ? this.formMedal.medalQty : 0
379
- };
380
- console.log("params:", params);
381
- const row = {
382
- id: Date.now(),
383
- ...params,
384
- medalObjName: subject ? `授予${subject.label}` : "",
385
- issuedQty: 0,
386
- wearDurat: this.formMedal.limitTmFlag === "Y" ? this.formMedal.wearDurat : 0
387
- };
388
- this.rows = this.rows.concat(row);
389
- this.dialogVisible = false;
390
- this.$message({
391
- type: "success",
392
- message: "保存成功"
393
- });
394
- },
395
- initColumnDrag() {
396
- if (this.isDestroyed) return;
397
- if (this.headerSortable && this.headerSortable.destroy) {
398
- this.headerSortable.destroy();
399
- this.headerSortable = null;
400
- }
401
- const table = this.$refs.medalTable;
402
- if (!table || !table.$el) return;
403
- const headerRow = table.$el.querySelector(".el-table__header-wrapper thead tr");
404
- if (!headerRow) return;
405
- this.headerSortable = Sortable.create(headerRow, {
406
- animation: 150,
407
- handle: ".header-draggable",
408
- draggable: "th",
409
- onEnd: (evt) => {
410
- const { oldIndex, newIndex } = evt;
411
- if (oldIndex == null || newIndex == null) return;
412
- if (oldIndex === newIndex) return;
413
- const from = oldIndex;
414
- const to = newIndex;
415
- if (from < 0 || to < 0 || from >= this.columns.length || to >= this.columns.length) return;
416
- const list = this.columns.slice();
417
- [list[from], list[to]] = [list[to], list[from]];
418
- this.columns = list;
419
- this.tableKey += 1;
420
- this.$nextTick(() => {
421
- this.initColumnDrag();
422
- });
423
- }
424
- });
425
- },
426
- formatConfeMode(value) {
427
- if (value === "4") return "手动发放";
428
- return value || "";
429
- },
430
- formatTmUnit(value) {
431
- if (value === "D") return "日";
432
- if (value === "M") return "月";
433
- if (value === "Y") return "年";
434
- return "";
435
- },
436
- formatDate(value) {
437
- if (!value) return "";
438
- const d = new Date(value);
439
- if (Number.isNaN(d.getTime())) return "";
440
- const yyyy = d.getFullYear();
441
- const mm = String(d.getMonth() + 1).padStart(2, "0");
442
- const dd = String(d.getDate()).padStart(2, "0");
443
- return `${yyyy}-${mm}-${dd}`;
444
- },
445
- onToggleActive(row) {
446
- const flag = row.activaFlag === "Y" ? "启用" : "停用";
447
- this.$message({
448
- type: "success",
449
- message: `已${flag}勋章「${row.medalName || row.medalNo}」`
450
- });
451
- },
452
- onPreview(row) {
453
- this.$alert(
454
- `勋章名称:${row.medalName}\n勋章编号:${row.medalNo}`,
455
- "勋章预览",
456
- {
457
- confirmButtonText: "确定"
458
- }
459
- );
460
- },
461
- onMore(row) {
462
- this.$message({
463
- type: "info",
464
- message: `更多操作:${row.medalName || row.medalNo}`
465
- });
466
- }
467
- }
468
- };
469
- </script>
470
-
471
- <style scoped>
472
- .medal-settings-page {
473
- padding: 24px;
474
- }
475
- .desc {
476
- margin-bottom: 12px;
477
- color: #666;
478
- }
479
- .toolbar {
480
- margin-bottom: 12px;
481
- }
482
- .create-form {
483
- max-height: 520px;
484
- overflow-y: auto;
485
- }
486
- .inline-group {
487
- display: flex;
488
- align-items: center;
489
- }
490
- .upload-block {
491
- display: flex;
492
- align-items: flex-start;
493
- margin-top: 12px;
494
- }
495
- .upload-label {
496
- width: 90px;
497
- flex-shrink: 0;
498
- padding-top: 4px;
499
- color: #606266;
500
- }
501
- .upload-content {
502
- flex: 1;
503
- }
504
- .upload-tip {
505
- margin-top: 6px;
506
- font-size: 12px;
507
- color: #909399;
508
- }
509
- .header-wrapper {
510
- display: inline-flex;
511
- align-items: center;
512
- }
513
- .header-draggable {
514
- cursor: move;
515
- }
516
- .header-label {
517
- white-space: nowrap;
518
- }
519
- .medal-icon {
520
- display: flex;
521
- justify-content: center;
522
- align-items: center;
523
- }
524
- .medal-icon img {
525
- width: 40px;
526
- height: 40px;
527
- border-radius: 4px;
528
- }
529
- </style>