|
@@ -141,11 +141,26 @@
|
|
|
</t-collapse-panel> -->
|
|
|
|
|
|
<t-collapse-panel value="3" header="数据">
|
|
|
+ <div class="form-item" v-if="props.pen.name==='tablePlus'">
|
|
|
+ <label class="label">数据源</label>
|
|
|
+ <t-select
|
|
|
+ v-model="dataSource"
|
|
|
+ placeholder="请选择"
|
|
|
+ @change="getDataSource"
|
|
|
+ >
|
|
|
+ <t-option key="api" value="api" label="API接口"/>
|
|
|
+ <t-option key="csv" value="csv" label="CSV文件"/>
|
|
|
+ <t-option key="excel" value="excel" label="从Excel导入"/>
|
|
|
+ </t-select>
|
|
|
+ </div>
|
|
|
<div class="t-space-item" v-if="props.pen.name==='tablePlus'">
|
|
|
- <div v-if="cell.col!==undefined&&cell.row!==undefined" class="flex between form-item py-12">
|
|
|
- <div style="line-height: 30px">
|
|
|
+ <div v-if="cell.row!==undefined" class="flex between form-item py-12">
|
|
|
+ <div v-if="cell.col!==undefined" style="line-height: 30px">
|
|
|
当前选中单元格 (第{{ cell.row }}行,第{{ cell.col}}列)
|
|
|
</div>
|
|
|
+ <div v-else style="line-height: 30px">
|
|
|
+ 当前选中行 (第{{ cell.row }}行)
|
|
|
+ </div>
|
|
|
<div>
|
|
|
<t-tooltip content="快捷绑定" placement="top">
|
|
|
<link-icon style="width: 13px;margin-right: 26px"class="hover ml-4" @click="onQuickBind()"/>
|
|
@@ -786,6 +801,50 @@
|
|
|
{{ propsDialog.placeholder }}
|
|
|
</div>
|
|
|
</t-dialog>
|
|
|
+
|
|
|
+ <t-dialog
|
|
|
+ v-if="apiDialog.show"
|
|
|
+ :visible="true"
|
|
|
+ class="data-dialog"
|
|
|
+ header="API接口"
|
|
|
+ @close="apiDialog.show = false"
|
|
|
+ @confirm="onConfirmAPI"
|
|
|
+ >
|
|
|
+ <div class="form-item mt-8">
|
|
|
+ <label>http地址</label>
|
|
|
+ <t-input
|
|
|
+ placeholder="请输入(临时请求,不会保存)"
|
|
|
+ v-model="apiDialog.url"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="form-item mt-8">
|
|
|
+ <label>请求方式</label>
|
|
|
+ <t-select v-model="apiDialog.method">
|
|
|
+ <t-option key="GET" value="GET" label="GET" />
|
|
|
+ <t-option key="POST" value="POST" label="POST" />
|
|
|
+ </t-select>
|
|
|
+ </div>
|
|
|
+ <div class="form-item mt-8">
|
|
|
+ <label>请求头</label>
|
|
|
+ <CodeEditor
|
|
|
+ :json="true"
|
|
|
+ :language="'json'"
|
|
|
+ v-model="apiDialog.headers"
|
|
|
+ class="mt-4"
|
|
|
+ style="height: 50px"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div v-if="apiDialog.method === 'POST'" class="form-item mt-8">
|
|
|
+ <label>请求体</label>
|
|
|
+ <CodeEditor
|
|
|
+ :json="true"
|
|
|
+ :language="'json'"
|
|
|
+ v-model="apiDialog.body"
|
|
|
+ class="mt-4"
|
|
|
+ style="height: 50px"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </t-dialog>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
@@ -815,6 +874,8 @@ import { defaultGradientColor, defaultPureColor } from '@/services/defaults';
|
|
|
import { getLe5le3d, getLe5leV, getLe5le2d } from '@/services/api';
|
|
|
import { EllipsisIcon, MoreIcon, LinkIcon, RelativityIcon, AddRectangleIcon, SearchIcon ,DeleteIcon, ArrowRightIcon, CloseIcon, ChevronLeftDoubleIcon, AddIcon, ViewListIcon } from 'tdesign-icons-vue-next';
|
|
|
import { s8 } from '@/services/random';
|
|
|
+import { importExcel } from '@/services/excel';
|
|
|
+import { importCSV } from '@/services/file';
|
|
|
|
|
|
const route = useRoute();
|
|
|
const router = useRouter();
|
|
@@ -1897,6 +1958,9 @@ const getPenData = (e)=>{
|
|
|
if(props.pen.calculative.activeCell){
|
|
|
cell.value.col = props.pen.calculative.activeCell.col;
|
|
|
cell.value.row = props.pen.calculative.activeCell.row;
|
|
|
+ }else if(props.pen.calculative.activeRow !== undefined){
|
|
|
+ cell.value.row = props.pen.calculative.activeRow;
|
|
|
+ cell.value.col = undefined;
|
|
|
}else{
|
|
|
cell.value.col = undefined;
|
|
|
cell.value.row = undefined;
|
|
@@ -1905,26 +1969,109 @@ const getPenData = (e)=>{
|
|
|
}
|
|
|
|
|
|
const onQuickBind = ()=>{
|
|
|
- if(cell.value.col !== undefined && cell.value.row !== undefined){
|
|
|
+ if(cell.value.row !== undefined){
|
|
|
if(!props.pen.realTimes){
|
|
|
props.pen.realTimes = [];
|
|
|
}
|
|
|
- let found = props.pen.realTimes.findIndex((item:any)=>{
|
|
|
- return item.key === `data.${cell.value.row}.${cell.value.col}`;
|
|
|
- });
|
|
|
- if(found === -1){
|
|
|
- props.pen.realTimes.push({
|
|
|
- label: `第${cell.value.row}行,第${cell.value.col}列`,
|
|
|
- key: `data.${cell.value.row}.${cell.value.col}`,
|
|
|
- type: 'float',
|
|
|
+ if(cell.value.col !== undefined){
|
|
|
+ let found = props.pen.realTimes.findIndex((item:any)=>{
|
|
|
+ return item.key === `data.${cell.value.row}.${cell.value.col}`;
|
|
|
});
|
|
|
- onBind(props.pen.realTimes[props.pen.realTimes.length-1]);
|
|
|
+ if(found === -1){
|
|
|
+ props.pen.realTimes.push({
|
|
|
+ label: `第${cell.value.row}行,第${cell.value.col}列`,
|
|
|
+ key: `data.${cell.value.row}.${cell.value.col}`,
|
|
|
+ type: 'float',
|
|
|
+ });
|
|
|
+ onBind(props.pen.realTimes[props.pen.realTimes.length-1]);
|
|
|
+ }else{
|
|
|
+ onBind(props.pen.realTimes[found]);
|
|
|
+ }
|
|
|
}else{
|
|
|
- onBind(props.pen.realTimes[found]);
|
|
|
+ let found = props.pen.realTimes.findIndex((item:any)=>{
|
|
|
+ return item.key === `data.${cell.value.row}`;
|
|
|
+ });
|
|
|
+ if(found === -1){
|
|
|
+ props.pen.realTimes.push({
|
|
|
+ label: `第${cell.value.row}行`,
|
|
|
+ key: `data.${cell.value.row}`,
|
|
|
+ type: 'array',
|
|
|
+ });
|
|
|
+ onBind(props.pen.realTimes[props.pen.realTimes.length-1]);
|
|
|
+ }else{
|
|
|
+ onBind(props.pen.realTimes[found]);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const dataSource = ref('');
|
|
|
+
|
|
|
+const getDataSource = async (e) => {
|
|
|
+ dataSource.value = '';
|
|
|
+ if (e === 'excel') {
|
|
|
+ let data = await importExcel();
|
|
|
+ if (Array.isArray(data) && Array.isArray(data[0])) {
|
|
|
+ meta2d.setValue({ id: props.pen.id, data: data, styles: [], mergeCells: [], colHeaders: false }, { doEvent: false });
|
|
|
+ } else {
|
|
|
+ MessagePlugin.warning("数据格式必需是二维数组");
|
|
|
+ }
|
|
|
+ } else if (e === 'csv') {
|
|
|
+ let data = await importCSV();
|
|
|
+ if (Array.isArray(data) && Array.isArray(data[0])) {
|
|
|
+ meta2d.setValue({ id: props.pen.id, data: data, styles: [], mergeCells: [], colHeaders: false }, { doEvent: false });
|
|
|
+ } else {
|
|
|
+ MessagePlugin.warning("数据格式必需是二维数组");
|
|
|
+ }
|
|
|
+ } else if (e === 'api') {
|
|
|
+ apiDialog.show = true;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const apiDialog = reactive<any>({
|
|
|
+ show: false,
|
|
|
+});
|
|
|
+
|
|
|
+const onConfirmAPI = async () => {
|
|
|
+ if (!apiDialog.url) {
|
|
|
+ MessagePlugin.warning('请输入API地址');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const res: Response = await fetch(apiDialog.url, {
|
|
|
+ headers: apiDialog.headers,
|
|
|
+ method: apiDialog.method || 'GET',
|
|
|
+ body: apiDialog.method === 'GET' ? undefined : JSON.stringify(apiDialog.body),
|
|
|
+ });
|
|
|
+ let data: any = JSON.parse(await res.text());
|
|
|
+ if (data.data) {
|
|
|
+ data = data.data;
|
|
|
+ }
|
|
|
+ if (data.list) {
|
|
|
+ data = data.list;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Array.isArray(data)) {
|
|
|
+ if (Array.isArray(data[0])) {
|
|
|
+ } else {
|
|
|
+ let _data = [];
|
|
|
+ data.forEach((item) => {
|
|
|
+ _data.push(Object.values(item));
|
|
|
+
|
|
|
+ })
|
|
|
+ data = _data;
|
|
|
+ }
|
|
|
+ if (Array.isArray(data) && Array.isArray(data[0])) {
|
|
|
+ meta2d.setValue({ id: props.pen.id, data: data, styles: [], mergeCells: [], colHeaders: false }, { doEvent: false });
|
|
|
+ MessagePlugin.success("导入成功");
|
|
|
+ } else {
|
|
|
+ MessagePlugin.warning("数据格式必需是二维数组");
|
|
|
+ }
|
|
|
+ apiDialog.show = false;
|
|
|
+ } else {
|
|
|
+ MessagePlugin.warning("数据格式必需是数组类型");
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
meta2d.on('click',getPenData);
|
|
|
getPenData({});
|
|
@@ -1974,12 +2121,13 @@ onUnmounted(() => {
|
|
|
color: var(--color);
|
|
|
font-weight: 700;
|
|
|
}
|
|
|
-
|
|
|
- .label {
|
|
|
- width: fix-content;
|
|
|
- font-size: 10px;
|
|
|
- line-height: 28px;
|
|
|
- color: var(--color-desc);
|
|
|
+ .real-times{
|
|
|
+ .label {
|
|
|
+ width: fix-content;
|
|
|
+ font-size: 10px;
|
|
|
+ line-height: 28px;
|
|
|
+ color: var(--color-desc);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.value {
|