arms-app 1.0.68 → 1.0.70
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.
- package/package.json +1 -1
- package/view/{5.vue → index.vue} +18 -47
- package/view/{4.vue → index2.vue} +29 -20
- package/view/1.js +0 -23
- package/view/1.vue +0 -117
- package/view/111.js +0 -35
- package/view/2.js +0 -90
- package/view/2.vue +0 -129
- package/view/3.js +0 -289
- package/view/3.vue +0 -289
- package/view/555.vue +0 -196
- package/view/CallRecordDetail.vue +0 -101
- package/view/ListedCompaniesView copy.vue +0 -238
- package/view/ListedCompaniesView.vue +0 -224
- package/view/ListedEnterprisesView.vue +0 -206
- package/view/ListedIncrementalEnterprisesView.vue +0 -195
- package/view/index.html +0 -51
- package/view//345/205/250/345/261/217.png +0 -0
- package/view//351/200/200/345/207/272/345/205/250/345/261/217.png +0 -0
package/view/555.vue
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<!-- 列拖拽示例页面 -->
|
|
3
|
-
<section class="draggable-columns-table-page">
|
|
4
|
-
<!-- 标题与说明 -->
|
|
5
|
-
<h1>列拖拽表格</h1>
|
|
6
|
-
<p class="desc">通过拖拽表头,使用 sortablejs 实现列换位。</p>
|
|
7
|
-
|
|
8
|
-
<!-- 表格:通过 columns 数组驱动列配置 -->
|
|
9
|
-
<el-table
|
|
10
|
-
ref="draggableTable"
|
|
11
|
-
:key="tableKey"
|
|
12
|
-
:data="rows"
|
|
13
|
-
border
|
|
14
|
-
stripe
|
|
15
|
-
style="width: 100%"
|
|
16
|
-
height="420"
|
|
17
|
-
>
|
|
18
|
-
<!-- 固定的序号列,不参与拖拽换位 -->
|
|
19
|
-
<el-table-column type="index" label="#" width="60" />
|
|
20
|
-
|
|
21
|
-
<!-- 动态业务列:所有可拖拽的列 -->
|
|
22
|
-
<el-table-column
|
|
23
|
-
v-for="col in columns"
|
|
24
|
-
:key="col.prop"
|
|
25
|
-
:prop="col.prop"
|
|
26
|
-
:label="col.label"
|
|
27
|
-
:width="col.width"
|
|
28
|
-
:min-width="col.minWidth"
|
|
29
|
-
:align="col.align || 'left'"
|
|
30
|
-
:header-align="col.headerAlign || col.align || 'left'"
|
|
31
|
-
>
|
|
32
|
-
<!-- 表头插槽:添加拖拽手柄,作为 sortablejs 的 handle -->
|
|
33
|
-
<template slot="header">
|
|
34
|
-
<div class="header-draggable">
|
|
35
|
-
<span class="header-label">{{ col.label }}</span>
|
|
36
|
-
</div>
|
|
37
|
-
</template>
|
|
38
|
-
<!-- 单元格内容:根据列配置动态渲染字段 -->
|
|
39
|
-
<template slot-scope="scope">
|
|
40
|
-
<span>{{ scope.row[col.prop] }}</span>
|
|
41
|
-
</template>
|
|
42
|
-
</el-table-column>
|
|
43
|
-
</el-table>
|
|
44
|
-
</section>
|
|
45
|
-
</template>
|
|
46
|
-
|
|
47
|
-
<script>
|
|
48
|
-
import Sortable from "sortablejs";
|
|
49
|
-
|
|
50
|
-
export default {
|
|
51
|
-
name: "DraggableColumnsTableView",
|
|
52
|
-
data() {
|
|
53
|
-
return {
|
|
54
|
-
// 表格行数据:示例客户信息
|
|
55
|
-
rows: [
|
|
56
|
-
{
|
|
57
|
-
id: 1,
|
|
58
|
-
name: "王小虎",
|
|
59
|
-
customerTag: "重点客户",
|
|
60
|
-
manager: "张三",
|
|
61
|
-
contribution: 12000,
|
|
62
|
-
pass1: 98,
|
|
63
|
-
pass2: 87,
|
|
64
|
-
pass3: 93,
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
id: 2,
|
|
68
|
-
name: "李小虎",
|
|
69
|
-
customerTag: "潜在客户",
|
|
70
|
-
manager: "李四",
|
|
71
|
-
contribution: 8600,
|
|
72
|
-
pass1: 88,
|
|
73
|
-
pass2: 90,
|
|
74
|
-
pass3: 85,
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
id: 3,
|
|
78
|
-
name: "赵六",
|
|
79
|
-
customerTag: "普通客户",
|
|
80
|
-
manager: "王五",
|
|
81
|
-
contribution: 5400,
|
|
82
|
-
pass1: 76,
|
|
83
|
-
pass2: 80,
|
|
84
|
-
pass3: 79,
|
|
85
|
-
},
|
|
86
|
-
],
|
|
87
|
-
// 列配置:用于驱动 el-table-column 渲染,同时作为拖拽排序的数据源
|
|
88
|
-
columns: [
|
|
89
|
-
{ prop: "name", label: "姓名", width: 160, align: "center" },
|
|
90
|
-
{ prop: "customerTag", label: "客户标签", width: 120, align: "center" },
|
|
91
|
-
{ prop: "manager", label: "客户人", width: 160, align: "center" },
|
|
92
|
-
{ prop: "contribution", label: "贡献积分", width: 120, align: "right", headerAlign: "center" },
|
|
93
|
-
{ prop: "pass1", label: "通关1", width: 100, align: "center" },
|
|
94
|
-
{ prop: "pass2", label: "通关2", width: 100, align: "center" },
|
|
95
|
-
{ prop: "pass3", label: "通关3", width: 100, align: "center" },
|
|
96
|
-
],
|
|
97
|
-
// sortablejs 实例,用于在组件销毁时释放
|
|
98
|
-
headerSortable: null,
|
|
99
|
-
// 用于强制重建 el-table,确保列顺序与数据完全同步
|
|
100
|
-
tableKey: 0,
|
|
101
|
-
isDestroyed: false,
|
|
102
|
-
};
|
|
103
|
-
},
|
|
104
|
-
mounted() {
|
|
105
|
-
// 表格渲染完成后,初始化表头拖拽能力
|
|
106
|
-
this.$nextTick(() => {
|
|
107
|
-
this.initColumnDrag();
|
|
108
|
-
});
|
|
109
|
-
},
|
|
110
|
-
beforeDestroy() {
|
|
111
|
-
// 组件销毁前销毁 sortable 实例,避免内存泄露
|
|
112
|
-
this.isDestroyed = true;
|
|
113
|
-
if (this.headerSortable && this.headerSortable.destroy) {
|
|
114
|
-
this.headerSortable.destroy();
|
|
115
|
-
this.headerSortable = null;
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
methods: {
|
|
119
|
-
// 初始化列拖拽:绑定在 ElementUI 表格头部行上
|
|
120
|
-
initColumnDrag() {
|
|
121
|
-
if (this.isDestroyed) return;
|
|
122
|
-
// 已存在实例时先销毁,避免重复绑定和内存泄漏
|
|
123
|
-
if (this.headerSortable && this.headerSortable.destroy) {
|
|
124
|
-
this.headerSortable.destroy();
|
|
125
|
-
this.headerSortable = null;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const table = this.$refs.draggableTable;
|
|
129
|
-
if (!table || !table.$el) return;
|
|
130
|
-
|
|
131
|
-
// ElementUI 表头 DOM:thead 里的第一行 tr
|
|
132
|
-
const headerRow = table.$el.querySelector(".el-table__header-wrapper thead tr");
|
|
133
|
-
if (!headerRow) return;
|
|
134
|
-
|
|
135
|
-
this.headerSortable = Sortable.create(headerRow, {
|
|
136
|
-
// 拖拽动画时长(毫秒)
|
|
137
|
-
animation: 150,
|
|
138
|
-
// 只允许拖拽 header-draggable 区域作为手柄
|
|
139
|
-
handle: ".header-draggable",
|
|
140
|
-
// 可被拖动的元素类型:表头单元格 th
|
|
141
|
-
draggable: "th",
|
|
142
|
-
// 拖拽结束时回调:根据新旧索引更新 columns 顺序
|
|
143
|
-
onEnd: (evt) => {
|
|
144
|
-
const { oldIndex, newIndex } = evt;
|
|
145
|
-
if (oldIndex == null || newIndex == null) return;
|
|
146
|
-
|
|
147
|
-
// 第 0 列是 index 序号列,从第 1 列开始才对应 columns[0]
|
|
148
|
-
const from = oldIndex - 1;
|
|
149
|
-
const to = newIndex - 1;
|
|
150
|
-
if (from < 0 || to < 0 || from >= this.columns.length || to >= this.columns.length) return;
|
|
151
|
-
|
|
152
|
-
// 交换 columns 中两列的位置,实现“换列”
|
|
153
|
-
const list = this.columns.slice();
|
|
154
|
-
[list[from], list[to]] = [list[to], list[from]];
|
|
155
|
-
this.columns = list;
|
|
156
|
-
|
|
157
|
-
// 强制重建表格组件,避免 ElementUI 内部列状态与 DOM 拖拽产生偏差,
|
|
158
|
-
// 重建后在下一个 tick 重新绑定 sortable
|
|
159
|
-
this.tableKey += 1;
|
|
160
|
-
this.$nextTick(() => {
|
|
161
|
-
this.initColumnDrag();
|
|
162
|
-
});
|
|
163
|
-
},
|
|
164
|
-
});
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
};
|
|
168
|
-
</script>
|
|
169
|
-
|
|
170
|
-
<style scoped>
|
|
171
|
-
.draggable-columns-table-page {
|
|
172
|
-
padding: 24px;
|
|
173
|
-
}
|
|
174
|
-
h1 {
|
|
175
|
-
margin: 0 0 12px;
|
|
176
|
-
font-size: 20px;
|
|
177
|
-
}
|
|
178
|
-
.desc {
|
|
179
|
-
margin: 0 0 16px;
|
|
180
|
-
color: #666;
|
|
181
|
-
}
|
|
182
|
-
.header-draggable {
|
|
183
|
-
display: inline-flex;
|
|
184
|
-
align-items: center;
|
|
185
|
-
cursor: move;
|
|
186
|
-
user-select: none;
|
|
187
|
-
}
|
|
188
|
-
.drag-icon {
|
|
189
|
-
margin-right: 4px;
|
|
190
|
-
font-size: 14px;
|
|
191
|
-
color: #999;
|
|
192
|
-
}
|
|
193
|
-
.header-label {
|
|
194
|
-
white-space: nowrap;
|
|
195
|
-
}
|
|
196
|
-
</style>
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="page">
|
|
3
|
-
<van-nav-bar title="外呼记录详情" left-arrow @click-left="onBack">
|
|
4
|
-
<template #right>
|
|
5
|
-
<van-icon name="edit" @click="toggleEdit" />
|
|
6
|
-
</template>
|
|
7
|
-
</van-nav-bar>
|
|
8
|
-
|
|
9
|
-
<van-form @submit="onSubmit">
|
|
10
|
-
<van-cell-group inset>
|
|
11
|
-
<van-field v-model="form.customer" label="客户姓名" required :readonly="!isEditing" placeholder="请输入" />
|
|
12
|
-
<van-field
|
|
13
|
-
v-model="form.content"
|
|
14
|
-
label="联系内容"
|
|
15
|
-
required
|
|
16
|
-
type="textarea"
|
|
17
|
-
:rows="4"
|
|
18
|
-
:readonly="!isEditing"
|
|
19
|
-
:maxlength="1000"
|
|
20
|
-
placeholder="请填写"
|
|
21
|
-
/>
|
|
22
|
-
<van-cell :border="false" class="content-footer-cell">
|
|
23
|
-
<template #title>
|
|
24
|
-
<div class="limit">{{ (form.content?.length || 0) }}/1000</div>
|
|
25
|
-
</template>
|
|
26
|
-
<template #value>
|
|
27
|
-
<span class="toggle-link" @click="showFull = true">展开</span>
|
|
28
|
-
</template>
|
|
29
|
-
</van-cell>
|
|
30
|
-
</van-cell-group>
|
|
31
|
-
</van-form>
|
|
32
|
-
<van-popup v-model:show="showFull" position="bottom" :style="{ height: '100%', width: '100%' }">
|
|
33
|
-
<div class="full-wrap">
|
|
34
|
-
<van-nav-bar title="联系内容" left-text="收起" left-arrow @click-left="showFull=false" />
|
|
35
|
-
<div class="full-body">
|
|
36
|
-
<van-field v-model="form.content" type="textarea" :rows="12" :readonly="!isEditing" :maxlength="1000" placeholder="请填写" />
|
|
37
|
-
</div>
|
|
38
|
-
<div class="full-footer">
|
|
39
|
-
<div class="limit">{{ (form.content?.length || 0) }}/1000</div>
|
|
40
|
-
<van-button size="small" type="primary" @click="showFull=false">收起</van-button>
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
</van-popup>
|
|
44
|
-
</div>
|
|
45
|
-
</template>
|
|
46
|
-
|
|
47
|
-
<script>
|
|
48
|
-
import { ref } from 'vue'
|
|
49
|
-
|
|
50
|
-
export default {
|
|
51
|
-
name: 'CallRecordDetail',
|
|
52
|
-
setup() {
|
|
53
|
-
const isEditing = ref(false)
|
|
54
|
-
const showFull = ref(false)
|
|
55
|
-
const form = ref({
|
|
56
|
-
customer: '北京银行金融科技部',
|
|
57
|
-
content: ''
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
const toggleEdit = () => {
|
|
61
|
-
isEditing.value = !isEditing.value
|
|
62
|
-
}
|
|
63
|
-
const onBack = () => {}
|
|
64
|
-
const onSubmit = () => {}
|
|
65
|
-
|
|
66
|
-
return { isEditing, form, showFull, toggleEdit, onBack, onSubmit }
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
</script>
|
|
70
|
-
|
|
71
|
-
<style scoped>
|
|
72
|
-
.page {
|
|
73
|
-
background-color: #f7f8fa;
|
|
74
|
-
min-height: 100vh;
|
|
75
|
-
}
|
|
76
|
-
.limit {
|
|
77
|
-
color: #969799;
|
|
78
|
-
font-size: 12px;
|
|
79
|
-
}
|
|
80
|
-
.toggle-link {
|
|
81
|
-
color: #1989fa;
|
|
82
|
-
font-size: 14px;
|
|
83
|
-
}
|
|
84
|
-
.full-wrap {
|
|
85
|
-
display: flex;
|
|
86
|
-
flex-direction: column;
|
|
87
|
-
height: 100%;
|
|
88
|
-
background: #fff;
|
|
89
|
-
}
|
|
90
|
-
.full-body {
|
|
91
|
-
padding: 12px 16px;
|
|
92
|
-
flex: 1;
|
|
93
|
-
overflow: auto;
|
|
94
|
-
}
|
|
95
|
-
.full-footer {
|
|
96
|
-
display: flex;
|
|
97
|
-
align-items: center;
|
|
98
|
-
justify-content: space-between;
|
|
99
|
-
padding: 8px 16px 16px;
|
|
100
|
-
}
|
|
101
|
-
</style>
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<section class="listed-companies-page">
|
|
3
|
-
<h1>并购企业</h1>
|
|
4
|
-
<div>
|
|
5
|
-
<el-form :model="filters" label-position="top" size="mini">
|
|
6
|
-
<el-row :gutter="12">
|
|
7
|
-
<el-col :span="5">
|
|
8
|
-
<el-form-item label="并购方名称">
|
|
9
|
-
<el-input v-model="filterAcquirer" placeholder="请输入" clearable size="mini" style="width: 100%" />
|
|
10
|
-
</el-form-item>
|
|
11
|
-
</el-col>
|
|
12
|
-
<el-col :span="5">
|
|
13
|
-
<el-form-item label="被并购方名称">
|
|
14
|
-
<el-input v-model="filterTarget" placeholder="请输入" clearable size="mini" style="width: 100%" />
|
|
15
|
-
</el-form-item>
|
|
16
|
-
</el-col>
|
|
17
|
-
<el-col :span="5">
|
|
18
|
-
<el-form-item label="交易方式">
|
|
19
|
-
<el-select v-model="filterMethod" placeholder="请选择" clearable size="mini" style="width: 100%">
|
|
20
|
-
<el-option v-for="opt in methodOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
|
21
|
-
</el-select>
|
|
22
|
-
</el-form-item>
|
|
23
|
-
</el-col>
|
|
24
|
-
<el-col :span="5">
|
|
25
|
-
<el-form-item label=" ">
|
|
26
|
-
<el-button type="primary" size="mini" @click="applyFilters">查询</el-button>
|
|
27
|
-
<el-button size="mini" @click="onResetFilters">重置</el-button>
|
|
28
|
-
</el-form-item>
|
|
29
|
-
</el-col>
|
|
30
|
-
</el-row>
|
|
31
|
-
</el-form>
|
|
32
|
-
</div>
|
|
33
|
-
|
|
34
|
-
<el-table
|
|
35
|
-
:data="pagedRows"
|
|
36
|
-
stripe
|
|
37
|
-
border
|
|
38
|
-
style="width: 100%"
|
|
39
|
-
@sort-change="onSortChange"
|
|
40
|
-
>
|
|
41
|
-
<el-table-column type="index" label="序号" width="56" align="center" header-align="center" />
|
|
42
|
-
<el-table-column prop="name" label="并购方" align="center" header-align="center">
|
|
43
|
-
<template slot-scope="scope">
|
|
44
|
-
<div class="name-row">
|
|
45
|
-
<span class="name">{{ scope.row.name }}</span>
|
|
46
|
-
<span class="code">({{ scope.row.code }})</span>
|
|
47
|
-
</div>
|
|
48
|
-
<div class="sub-row">
|
|
49
|
-
<el-tag size="mini">{{ scope.row.exchange }}</el-tag>
|
|
50
|
-
<el-tag size="mini" type="info">{{ scope.row.region }}</el-tag>
|
|
51
|
-
</div>
|
|
52
|
-
</template>
|
|
53
|
-
</el-table-column>
|
|
54
|
-
<el-table-column prop="customerTags" label="客户标签" align="center" header-align="center">
|
|
55
|
-
<template slot-scope="scope">
|
|
56
|
-
<div class="tag-list">
|
|
57
|
-
<el-tag v-for="(t, i) in (scope.row.customerTags || [scope.row.customerLevel])" :key="i" size="mini" type="info">{{ t }}</el-tag>
|
|
58
|
-
</div>
|
|
59
|
-
</template>
|
|
60
|
-
</el-table-column>
|
|
61
|
-
<el-table-column prop="targetName" label="被并购方" align="center" header-align="center" />
|
|
62
|
-
<el-table-column prop="targetShortName" label="被并购方简称" align="center" header-align="center" />
|
|
63
|
-
<el-table-column prop="industry" label="行业" align="center" header-align="center" />
|
|
64
|
-
<el-table-column prop="region" label="地区" align="center" header-align="center" />
|
|
65
|
-
<el-table-column prop="startDate" label="开始时间" sortable="custom" align="center" header-align="center">
|
|
66
|
-
<template slot-scope="scope">{{ formatDate(scope.row.startDate) }}</template>
|
|
67
|
-
</el-table-column>
|
|
68
|
-
<el-table-column prop="closingDate" label="完成时间" sortable="custom" align="center" header-align="center">
|
|
69
|
-
<template slot-scope="scope">{{ formatDate(scope.row.closingDate) }}</template>
|
|
70
|
-
</el-table-column>
|
|
71
|
-
<el-table-column prop="tradeStatus" label="交易状态" align="center" header-align="center" />
|
|
72
|
-
<el-table-column prop="tradeMethod" label="交易方式" align="center" header-align="center">
|
|
73
|
-
<template slot-scope="scope">{{ methodLabel(scope.row.tradeMethod) }}</template>
|
|
74
|
-
</el-table-column>
|
|
75
|
-
<el-table-column prop="amount" label="交易金额" align="center" header-align="center" sortable="custom">
|
|
76
|
-
<template slot-scope="scope">{{ formatCurrency(scope.row.amount) }}</template>
|
|
77
|
-
</el-table-column>
|
|
78
|
-
<el-table-column prop="amountCNY" label="交易金额(人民币)" align="center" header-align="center">
|
|
79
|
-
<template slot-scope="scope">{{ formatCurrency(scope.row.amountCNY) }}</template>
|
|
80
|
-
</el-table-column>
|
|
81
|
-
<el-table-column prop="equityPercent" label="交易股权" align="center" header-align="center" sortable="custom">
|
|
82
|
-
<template slot-scope="scope">{{ (scope.row.equityPercent != null ? scope.row.equityPercent : 0) + '%' }}</template>
|
|
83
|
-
</el-table-column>
|
|
84
|
-
<el-table-column prop="valuation" label="估值(人民币)" align="center" header-align="center" sortable="custom">
|
|
85
|
-
<template slot-scope="scope">{{ formatCurrency(scope.row.valuation) }}</template>
|
|
86
|
-
</el-table-column>
|
|
87
|
-
</el-table>
|
|
88
|
-
|
|
89
|
-
<div>
|
|
90
|
-
<el-pagination
|
|
91
|
-
layout="prev, pager, next, sizes, total"
|
|
92
|
-
:current-page.sync="page.current"
|
|
93
|
-
:page-size.sync="page.size"
|
|
94
|
-
:page-sizes="[10,20,30,50]"
|
|
95
|
-
:total="filteredRows.length"
|
|
96
|
-
@current-change="onPageChange"
|
|
97
|
-
@size-change="onSizeChange"
|
|
98
|
-
/>
|
|
99
|
-
</div>
|
|
100
|
-
</section>
|
|
101
|
-
|
|
102
|
-
</template>
|
|
103
|
-
|
|
104
|
-
<script>
|
|
105
|
-
import { mapState, mapMutations } from 'vuex';
|
|
106
|
-
export default {
|
|
107
|
-
name: 'ListedCompaniesView',
|
|
108
|
-
data() {
|
|
109
|
-
return {
|
|
110
|
-
keyword: '',
|
|
111
|
-
methodOptions: [
|
|
112
|
-
{ label: '现金', value: 'cash' },
|
|
113
|
-
{ label: '股票发行', value: 'stock' },
|
|
114
|
-
{ label: '混合', value: 'hybrid' }
|
|
115
|
-
],
|
|
116
|
-
sort: { prop: '', order: '' },
|
|
117
|
-
page: { current: 1, size: 10 },
|
|
118
|
-
rows: [
|
|
119
|
-
{ name: '博雅医药', code: '000013', exchange: '创业板', region: '四川', industry: '医药', customerLevel: 'NK', customerTags: ['NK','电子产品厂','后备供应商'], targetName: '华康制药', targetShortName: '华康', startDate: '2024-01-10', closingDate: '2024-03-28', tradeStatus: '已完成', tradeMethod: 'cash', amount: 120000000, amountCNY: 120000000, equityPercent: 35, valuation: 350000000 },
|
|
120
|
-
{ name: '优选消费', code: '000014', exchange: '沪深A股', region: '福建', industry: '消费', customerLevel: 'A', targetName: '乐享食品', targetShortName: '乐享', startDate: '2019-06-02', closingDate: '2019-07-11', tradeStatus: '已完成', tradeMethod: 'stock', amount: 90000000, amountCNY: 90000000, equityPercent: 20, valuation: 260000000 },
|
|
121
|
-
{ name: '恒材材料', code: '000015', exchange: '科创板', region: '上海', industry: '材料', customerLevel: 'B', customerTags: ['B','新材料','重点供应商'], targetName: '新材科技', targetShortName: '新材', startDate: '2024-07-01', closingDate: '2024-09-20', tradeStatus: '已完成', tradeMethod: 'hybrid', amount: 135000000, amountCNY: 135000000, equityPercent: 28, valuation: 420000000 },
|
|
122
|
-
{ name: '联通通信', code: '000016', exchange: '沪深A股', region: '广东', industry: '通信', customerLevel: 'C', targetName: '朗讯通讯', targetShortName: '朗讯', startDate: '2015-08-01', closingDate: '2015-10-12', tradeStatus: '已完成', tradeMethod: 'cash', amount: 75000000, amountCNY: 75000000, equityPercent: 15, valuation: 180000000 },
|
|
123
|
-
{ name: '远景能源', code: '000017', exchange: '沪深A股', region: '内蒙古', industry: '能源', customerLevel: 'A', targetName: '清源电力', targetShortName: '清源', startDate: '2020-03-01', closingDate: '2020-05-06', tradeStatus: '已完成', tradeMethod: 'stock', amount: 210000000, amountCNY: 210000000, equityPercent: 42, valuation: 680000000 },
|
|
124
|
-
{ name: '未来科技', code: '000018', exchange: '科创板', region: '上海', industry: '科技', customerLevel: 'S', targetName: '数云科技', targetShortName: '数云', startDate: '2022-12-20', closingDate: '2023-02-18', tradeStatus: '已完成', tradeMethod: 'hybrid', amount: 420000000, amountCNY: 420000000, equityPercent: 51, valuation: 980000000 },
|
|
125
|
-
{ name: '工匠制造', code: '000019', exchange: '沪深A股', region: '安徽', industry: '制造', customerLevel: 'B', targetName: '精工机械', targetShortName: '精工', startDate: '2021-02-10', closingDate: '2021-03-30', tradeStatus: '已完成', tradeMethod: 'cash', amount: 56000000, amountCNY: 56000000, equityPercent: 18, valuation: 150000000 },
|
|
126
|
-
{ name: '卓越金融', code: '000020', exchange: '港股', region: '香港', industry: '金融', customerLevel: 'A', targetName: '恒盛资管', targetShortName: '恒盛', startDate: '2014-10-20', closingDate: '2014-12-01', tradeStatus: '已完成', tradeMethod: 'stock', amount: 320000000, amountCNY: 320000000, equityPercent: 33, valuation: 760000000 },
|
|
127
|
-
{ name: '广域地产', code: '000021', exchange: '沪深A股', region: '广东', industry: '地产', customerLevel: 'B', targetName: '新城置地', targetShortName: '新城', startDate: '2018-09-02', closingDate: '2018-11-07', tradeStatus: '已完成', tradeMethod: 'hybrid', amount: 270000000, amountCNY: 270000000, equityPercent: 25, valuation: 500000000 },
|
|
128
|
-
{ name: '星海科技', code: '000022', exchange: '科创板', region: '北京', industry: '科技', customerLevel: 'C', targetName: '极光智能', targetShortName: '极光', startDate: '2022-04-05', closingDate: '2022-06-10', tradeStatus: '已完成', tradeMethod: 'stock', amount: 600000000, amountCNY: 600000000, equityPercent: 60, valuation: 1200000000 }
|
|
129
|
-
]
|
|
130
|
-
};
|
|
131
|
-
},
|
|
132
|
-
computed: {
|
|
133
|
-
...mapState('listedCompanies', ['filters']),
|
|
134
|
-
filterAcquirer: {
|
|
135
|
-
get() { return this.filters.acquirer; },
|
|
136
|
-
set(v) { this.setFilterField({ key: 'acquirer', value: v }); }
|
|
137
|
-
},
|
|
138
|
-
filterTarget: {
|
|
139
|
-
get() { return this.filters.target; },
|
|
140
|
-
set(v) { this.setFilterField({ key: 'target', value: v }); }
|
|
141
|
-
},
|
|
142
|
-
filterMethod: {
|
|
143
|
-
get() { return this.filters.method; },
|
|
144
|
-
set(v) { this.setFilterField({ key: 'method', value: v }); }
|
|
145
|
-
},
|
|
146
|
-
filteredRows() {
|
|
147
|
-
const kw = (this.keyword || '').trim().toLowerCase();
|
|
148
|
-
const acq = (this.filters.acquirer || '').trim().toLowerCase();
|
|
149
|
-
const tgt = (this.filters.target || '').trim().toLowerCase();
|
|
150
|
-
const method = this.filters.method || '';
|
|
151
|
-
return this.rows.filter(r => {
|
|
152
|
-
const okKw = kw ? (r.name.toLowerCase().includes(kw) || r.code.toLowerCase().includes(kw)) : true;
|
|
153
|
-
const okAcq = acq ? r.name.toLowerCase().includes(acq) : true;
|
|
154
|
-
const okTgt = tgt ? (r.targetName || '').toLowerCase().includes(tgt) : true;
|
|
155
|
-
const okMethod = method ? r.tradeMethod === method : true;
|
|
156
|
-
return okKw && okAcq && okTgt && okMethod;
|
|
157
|
-
});
|
|
158
|
-
},
|
|
159
|
-
sortedRows() {
|
|
160
|
-
const arr = this.filteredRows.slice();
|
|
161
|
-
const prop = this.sort.prop;
|
|
162
|
-
const order = this.sort.order;
|
|
163
|
-
if (!prop || !order) return arr;
|
|
164
|
-
arr.sort((a, b) => {
|
|
165
|
-
const va = a[prop];
|
|
166
|
-
const vb = b[prop];
|
|
167
|
-
if (prop === 'closingDate' || prop === 'listedDate') {
|
|
168
|
-
const ta = new Date(va).getTime();
|
|
169
|
-
const tb = new Date(vb).getTime();
|
|
170
|
-
return order === 'ascending' ? ta - tb : tb - ta;
|
|
171
|
-
}
|
|
172
|
-
if (typeof va === 'number' && typeof vb === 'number') {
|
|
173
|
-
return order === 'ascending' ? va - vb : vb - va;
|
|
174
|
-
}
|
|
175
|
-
const sa = String(va || '').localeCompare(String(vb || ''));
|
|
176
|
-
return order === 'ascending' ? sa : -sa;
|
|
177
|
-
});
|
|
178
|
-
return arr;
|
|
179
|
-
},
|
|
180
|
-
pagedRows() {
|
|
181
|
-
const start = (this.page.current - 1) * this.page.size;
|
|
182
|
-
return this.filteredRows.slice(start, start + this.page.size);
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
methods: {
|
|
186
|
-
...mapMutations('listedCompanies', ['setFilters', 'setFilterField', 'resetFilters']),
|
|
187
|
-
onSearch() {},
|
|
188
|
-
formatDate(d) {
|
|
189
|
-
if (!d) return '';
|
|
190
|
-
const dt = new Date(d);
|
|
191
|
-
const y = dt.getFullYear();
|
|
192
|
-
const m = String(dt.getMonth() + 1).padStart(2, '0');
|
|
193
|
-
const day = String(dt.getDate()).padStart(2, '0');
|
|
194
|
-
return `${y}-${m}-${day}`;
|
|
195
|
-
},
|
|
196
|
-
statusTagType(st) {
|
|
197
|
-
if (st === '正常') return 'success';
|
|
198
|
-
if (st === '风险') return 'warning';
|
|
199
|
-
if (st === '退市') return 'danger';
|
|
200
|
-
return 'info';
|
|
201
|
-
},
|
|
202
|
-
methodLabel(v) {
|
|
203
|
-
if (v === 'cash') return '现金';
|
|
204
|
-
if (v === 'stock') return '股票发行';
|
|
205
|
-
if (v === 'hybrid') return '混合';
|
|
206
|
-
return '—';
|
|
207
|
-
},
|
|
208
|
-
formatCurrency(n) {
|
|
209
|
-
const v = Number(n || 0);
|
|
210
|
-
return v.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
211
|
-
},
|
|
212
|
-
formatNumber(n) {
|
|
213
|
-
const v = Number(n || 0);
|
|
214
|
-
return v.toLocaleString('zh-CN');
|
|
215
|
-
},
|
|
216
|
-
onSortChange({ prop, order }) {
|
|
217
|
-
this.sort = { prop, order };
|
|
218
|
-
},
|
|
219
|
-
applyFilters() {
|
|
220
|
-
this.page.current = 1;
|
|
221
|
-
},
|
|
222
|
-
onResetFilters() {
|
|
223
|
-
this.resetFilters();
|
|
224
|
-
this.page.current = 1;
|
|
225
|
-
},
|
|
226
|
-
onPageChange(page) {
|
|
227
|
-
this.page.current = page;
|
|
228
|
-
},
|
|
229
|
-
onSizeChange(size) {
|
|
230
|
-
this.page.size = size;
|
|
231
|
-
this.page.current = 1;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
</script>
|
|
236
|
-
|
|
237
|
-
<style scoped>
|
|
238
|
-
</style>
|