Xpages 遍历视图并进行更改的最佳方式 [英] Xpages best way to loop through view and make changes

查看:28
本文介绍了Xpages 遍历视图并进行更改的最佳方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题让我发疯.

我有一个带有类别的文档视图.现在文档的顺序是任意的,但我想为用户提供一种简单的方法来向上或向下移动类别中的文档.所以我在视图中有向上/向下箭头.

I have a view of documents with categories. The docs are in an arbitrary order now but I want to provide the users an easy way to move docs within categories up or down. So I have up/down arrows within the view.

我在箭头后面有 SSJS 代码,可以更改文档中的顺序"值,因此它们会向上或向下移动(在我的选择中,任务字段显示顺序).

I have SSJS code behind the arrows that changes the "order" value in the docs so they will move up or down (in my pick the task field is showing the order).

我的问题是它间歇性地工作.我认为原因是因为当我在循环中时文档的顺序正在改变.我尝试将视图上的自动更新设置设置为手动,但它似乎仍然不起作用.

My problem is that it works intermittently. I think the reason is because the order of the docs is being changed while I am in the loop. I tried setting the auto-update setting on the view to manual, but it still seems to not work.

也许我正在努力.我真的只需要更改 2 个文档,一个是用户选择的,另一个是他们将其移动到的.抓住那些也许会更简单?

Maybe I am making this way to hard. I really only need to change 2 docs, the one the user chose and the one that they are moving it to. Would maybe be simpler just to grab those?

function mveItm(mveDir,mveCat,curOrd) {

    var curOrdStr:String = String(curOrd);
    var tarOrd:Integer;
    var tarOrdStr:String;
    var doc:NotesDocument;
    var lstOrd:Integer;
    var fstOrd:Integer;

    //Grab Collection In Order
    var tskView = database.getView("(dbAllPCTasksAutoUpdateFalse)");
    tskView.refresh();
    tskView.setAutoUpdate(false);

    var veCol:NotesViewEntryCollection = tskView.getAllEntriesByKey(mveCat);

    //Set First and Last Order Number
    var fstOrd = 10
    var lstOrd = veCol.getCount() * 10;

    //If the user has clicked move Higher on the last item 
    //or move down on the first, then ignore
    if (mveDir == "Lower" && fstOrd == curOrd) 
    {return}
    if (mveDir == "Higher" && lstOrd == curOrd) 
    {return}

    //Move Higher
    if (mveDir == "Higher") {

    //Set target order
    tarOrd = curOrd + 10;
    tarOrdStr = String(tarOrd);

    //Loop through viewEntryCollection and process
    var entry:NotesViewEntry = veCol.getFirstEntry();
    while (entry != null) {     

        doc = entry.getDocument()

        //Where are we in the loop
        var n:String = String(entry.getDocument().getItemValueInteger("order"));

        //If the number we are on matches the number that was selected to be changed
        //Change the current number to the target number 
        if (n == curOrdStr)
        {           
        print ("We are in order");
        print ("This is the one we are on..." + n);
        print ("This is the one we passed in..." + String(curOrdStr));
        print ("This is the target..." + String(tarOrd));
        doc.replaceItemValue("order",tarOrd);
        doc.save;   
        }

        //If the number we are on matches the number that was the target
        //Change the number we are on to the selected order number 
        if (n == tarOrdStr)
        { 
        doc.replaceItemValue("order",curOrd);
        doc.save;
        }

        var tmpentry:NotesViewEntry = veCol.getNextEntry(entry);
        entry.recycle();
        entry = tmpentry;
    }
    }

    //Move down
    if (mveDir == "Lower") {

        //Set target order
        tarOrd = curOrd - 10;
        tarOrdStr = String(tarOrd);

        //Loop through viewEntryCollection and add to DocumentCollection
        var entry:NotesViewEntry = veCol.getFirstEntry();
        while (entry != null) {

            doc = entry.getDocument()

            //Where are we in the loop
            var n:String = String(entry.getDocument().getItemValueInteger("order"));

            //If the number we are on matches the number that was selected to be changed
            //Change the current number to the target number 

            if (n == curOrdStr)
            {   
            //doc = entry.getDocument()
            doc.replaceItemValue("order",tarOrd);
            doc.save;   
            }

            //If the number we are on matches the number that was the target
            //Change the number we are on to the selected order number 
            if (n == tarOrdStr)
            //Change the current number to the target number and change everyone after that to -10
            //if (movDwn == true)
            { 
            doc.replaceItemValue("order",curOrd);
            doc.save;
            }

            var tmpentry:NotesViewEntry = veCol.getNextEntry(entry);
            entry.recycle();
            entry = tmpentry;

        }
    }   

    tskView.setAutoUpdate(true);
    tskView.refresh();

    //resetCategories(mveCat);
    return true;
}

我在这里发布我的完整解决方案.代码在最后,我会解释我做了什么来解决这个问题.感谢 David 和 Knut Hermann 为我提供的帮助 - 请在此处查看 Knut 的帖子.

I am posting my full solution here. The code is at the end, I will explain what I did to solve this. Kudos to help from David and from Knut Hermann for giving me assistance - see Knut's post here.

Xpages 得到处理下一个 rowData 或 Doc 重复

我的问题如下:用户可以输入带有类别的文档(我的示例是操作系统"和软件".我希望用户可以通过重复控件中的箭头轻松订购它们.它们也必须是能够选择多个要删除的文档和添加文档,并且顺序总是正确的.只是为了让它更难,我为该类别添加了一个过滤器,因此用户可能会看到所有类别或一个(这个解决方案会起作用)也适用于多个类别).

My problem was as follows: The user can enter docs with categories(my examples were "OS" and "Software". I want to them to be easily ordered by the user with arrows in the repeat control. They must also be able to select multiple docs to delete, and to add docs, and the order will always be correct. Just to make it harder I put in a filter for the category, so the user might see all categories or one (and this solution would work for more than one category as well).

实际的订单变更并不太难.我意识到我不必浏览一个类别中的所有文档,只需获取用户选择的文档,然后根据他们想做的事情选择更高或更低的文档,然后交换位置.那部分不是太难(参见库中的 mveTsk 方法.

The actual change of order is not too difficult. I realized that I do not have to go through all the docs in a category, just get the doc the user selected, and either the next higher or next lower, depending on what they want to do, and swap positions. That part is not too difficult (see method mveTsk in the library.

难点在于确定是否显示向上或向下移动箭头.如果项目是第一个,则不能显示向下箭头,如果它是最后一个,则不能显示.此外,如果用户删除了一个或两个或三个项目,然后我必须重新排序这些项目.

The difficult part is to determine whether or not to display up or down move arrows. Can't display a down arrow if the the item is the first one, can't display up if it was the last. Also, if a user deletes an item or two or three, then I must reorder the items.

我认为这个解决方案很好,应该适用于许多不同的情况.

I think this solution is a good one, and should work in many different situations.

==============================

============================

完整代码:

[无法输入所有代码]这里是我认为最重要的

[Cannot enter all the code] Here is what I think is most importatnt

<?xml version="1.0" encoding="UTF-8"?>
<xp:view
    xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xe="http://www.ibm.com/xsp/coreex"
    xmlns:xc="http://www.ibm.com/xsp/custom"
    style="font-size:8pt">
    <xp:this.data>
        <xp:dominoView
            var="view1"
            viewName="(xpAllPCBuilds)" />
    </xp:this.data>
    <xp:this.resources>
        <xp:styleSheet
            href="/custom.css" />
    </xp:this.resources>
    <xp:this.beforePageLoad><![CDATA[#{javascript:viewScope.put("rows","5")}]]></xp:this.beforePageLoad>

    <xe:widgetContainer id="widgetContainerView" style="width:99.00%">

        <xp:panel>
            <xp:repeat
                id="repeat1"
                var="rowData"
                indexVar="repeatIndex"
                value="#{view1}"
            >
                <xp:this.facets>
                    <xp:text
                        disableTheme="true"
                        xp:key="header"
                        escape="false">
                        <xp:this.value><![CDATA[<table class='lotusTable repeatRowColors' border='0' cellspacing='0' cellpadding='0'>
<tr class ='lotusFirst lotusSort scope='col'>
<th></th>
<th class ='lotusBold'>Employee Name</th>
<th class ='lotusBold'>Computer</th>
<th class ='lotusBold'>Create Date</th>
<th class ='lotusBold'>Create User</th>
<th class ='lotusBold'>ID</th>
</tr>
</thead>]]>
                        </xp:this.value>
                        <xp:panel id="pagerPnlTop">
                            <xp:table
                                styleClass="lotusPaging lotusPagingTop"
                                style="width:100%">
                                <xp:tr>
                                    <xp:td styleClass="lotusLeft">
                                        <xp:panel
                                            themeId="Panel.left"
                                            styleClass="xspRowCount">


                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                        </xp:panel>
                                    </xp:td>
                                    <xp:td styleClass="lotusRight">


                                    </xp:td>
                                </xp:tr>
                            </xp:table>
                        </xp:panel>
                    </xp:text>
                    <xp:text
                        disableTheme="true"
                        xp:key="footer"
                        escape="false"
                    >
                        <xp:this.value>
                            <![CDATA[</table>]]></xp:this.value>
                        <xp:panel id="pagerPnlBottom">
                            <xp:table
                                styleClass="lotusPaging lotusPagingTop"
                                style="width:100%"
                            >
                                <xp:tr>
                                    <xp:td styleClass="lotusLeft">
                                        <xp:panel
                                            themeId="Panel.left"
                                            styleClass="xspRowCount"
                                        >
                                            <xp:label
                                                value="Show: "
                                                id="label1"
                                            />
                                            <xp:link
                                                text="5"
                                                id="link2"
                                            >
                                                <xp:this.style>
                                                    <![CDATA[#{javascript:if (viewScope.get("rows") == 5)
{return "color:#808080;font-weight:normal;"}
else
{return "font-weight:bold"}}]]>
                                                </xp:this.style>
                                                <xp:eventHandler
                                                    event="onclick"
                                                    submit="true"
                                                    refreshMode="complete"
                                                >
                                                    <xp:this.action>
                                                        <![CDATA[#{javascript:var numEntries = 5;
viewScope.rows = numEntries;
var dt = getComponent("repeat1"); 
if(dt != null && dt.getRowCount() > 0) { 
        dt.setFirst(0); 
}}]]>
                                                    </xp:this.action>
                                                </xp:eventHandler>
                                            </xp:link>
                                            &#160;
                                            <xp:label
                                                value="|"
                                                id="label2"
                                                themeId="Text.smallSeparator"
                                            />
                                            &#160;
                                            <xp:link
                                                text="10"
                                                id="link3"
                                            >
                                                <xp:this.style>
                                                    <![CDATA[#{javascript:if (viewScope.get("rows") == 10)
{return "color:#808080;font-weight:normal;"}
else
{return "font-weight:bold"}}]]>
                                                </xp:this.style>
                                                <xp:eventHandler
                                                    event="onclick"
                                                    submit="true"
                                                    refreshMode="complete"
                                                >
                                                    <xp:this.action>
                                                        <![CDATA[#{javascript:var numEntries = 10;
viewScope.rows = numEntries;
var dt = getComponent("repeat1"); 
if(dt != null && dt.getRowCount() > 0) { 
        dt.setFirst(0); 
}}]]>
                                                    </xp:this.action>
                                                </xp:eventHandler>
                                            </xp:link>
                                            &#160;
                                            <xp:label
                                                value="|"
                                                id="label3"
                                                themeId="Text.smallSeparator"
                                            />
                                            &#160;
                                            <xp:link
                                                text="25"
                                                id="link4"
                                            >
                                                <xp:this.style>
                                                    <![CDATA[#{javascript:if (viewScope.get("rows") == 25)
{return "color:#808080;font-weight:normal;"}
else
{return "font-weight:bold"}}]]>
                                                </xp:this.style>
                                                <xp:eventHandler
                                                    event="onclick"
                                                    submit="true"
                                                    refreshMode="complete"
                                                >
                                                    <xp:this.action>
                                                        <![CDATA[#{javascript:var numEntries = 25;
viewScope.rows = numEntries;
var dt = getComponent("repeat1"); 
if(dt != null && dt.getRowCount() > 0) { 
        dt.setFirst(0); 
}}]]>
                                                    </xp:this.action>
                                                </xp:eventHandler>
                                            </xp:link>
                                            &#160;
                                            <xp:label
                                                value="|"
                                                id="label4"
                                                themeId="Text.smallSeparator"
                                            />
                                            &#160;
                                            <xp:link
                                                text="50"
                                                id="link6"
                                            >
                                                <xp:this.style>
                                                    <![CDATA[#{javascript:if (viewScope.get("rows") == 50)
{return "color:#808080;font-weight:normal;"}
else
{return "font-weight:bold"}}]]>
                                                </xp:this.style>
                                                <xp:eventHandler
                                                    event="onclick"
                                                    submit="true"
                                                    refreshMode="complete"
                                                >
                                                    <xp:this.action>
                                                        <![CDATA[#{javascript:var numEntries = 50;
viewScope.rows = numEntries;
var dt = getComponent("repeat1"); 
if(dt != null && dt.getRowCount() > 0) { 
        dt.setFirst(0); 
}}]]>
                                                    </xp:this.action>
                                                </xp:eventHandler>
                                            </xp:link>
                                            &#160;
                                            <xp:label
                                                value="|"
                                                id="label5"
                                                themeId="Text.smallSeparator"
                                            />
                                            &#160;
                                            <xp:link
                                                text="100"
                                                id="link7"
                                            >
                                                <xp:this.style>
                                                    <![CDATA[#{javascript:if (viewScope.get("rows") == 100)
{return "color:#808080;font-weight:normal;"}
else
{return "font-weight:bold"}}]]>
                                                </xp:this.style>
                                                <xp:eventHandler
                                                    event="onclick"
                                                    submit="true"
                                                    refreshMode="complete"
                                                >
                                                    <xp:this.action>
                                                        <![CDATA[#{javascript:var numEntries = 100;
viewScope.rows = numEntries;
var dt = getComponent("repeat1"); 
if(dt != null && dt.getRowCount() > 0) { 
        dt.setFirst(0); 
}}]]>
                                                    </xp:this.action>
                                                </xp:eventHandler>
                                            </xp:link>
                                            &#160;
                                            <xp:label
                                                value=" entries"
                                                id="label6"
                                            />
                                        </xp:panel>
                                    </xp:td>
                                    <xp:td styleClass="lotusRight">
                                        <xp:pager
                                            xp:key="headerPager"
                                            layout="Previous Group Next"
                                            for="repeat1"
                                            id="pager5"
                                            style="font-weight:inherit"
                                            styleClass="pagerTopRight"
                                        />
                                    </xp:td>
                                </xp:tr>
                            </xp:table>
                        </xp:panel>
                    </xp:text>
                </xp:this.facets>
                <xp:this.rows><![CDATA[#{javascript:var rows:Integere = viewScope.get("rows");
if (rows == null)
{return 5}
else
{return rows}}]]></xp:this.rows>
                <xp:tr id="rowDataContainer">
                    <xp:td
                        style="width:20px;min-width:20px;max-width: 20px;"
                    >
                        <xc:ccRowSelectCheckBox
                            docID="#{javascript:rowData.getNoteID()}"
                            selectedClass="selectedRow"
                            containerID="rowDataContainer"
                        />

                    </xp:td>
                    <xp:td
                        style="width:200px;min-width:200px;max-width: 200px;"
                    >
                        <xp:link
                            escape="true"
                            id="link1"
                            value=""
                        >
                            <xp:this.text><![CDATA[#{javascript:rowData.getColumnValue("employeeName")}]]></xp:this.text>
                            <xp:eventHandler
                                event="onclick"
                                submit="true"
                                refreshMode="complete"
                            >
                                <xp:this.action>
                                    <xp:openPage
                                        name="xpFormPCBuild.xsp"
                                        target="openDocument"
                                    >
                                        <xp:this.documentId><![CDATA[#{javascript:rowData.getDocument().getUniversalID()}]]></xp:this.documentId>
                                    </xp:openPage>
                                </xp:this.action>
                            </xp:eventHandler>
                        </xp:link>
                    </xp:td>
                    <xp:td
                        style="width:75px;min-width:75px;max-width:75px;">
                        <xp:text
                            escape="true"
                            id="computedField2">
                            <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("computerName");}]]>
                            </xp:this.value>
                        </xp:text>
                    </xp:td>
                    <xp:td
                        style="width:100px;min-width:100px;max-width:100px;">
                        <xp:text
                            escape="true"
                            id="computedField3">
                            <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("CrtDte");}]]>
                            </xp:this.value>
                        </xp:text>
                    </xp:td>
                    <xp:td
                        style="width:150px;min-width:150px;max-width: 150px;">
                        <xp:text
                            escape="true"
                            id="computedField4">
                            <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("crtUsr");}]]>
                            </xp:this.value>
                        </xp:text>
                    </xp:td>
                    <xp:td>
                        <xp:text
                            escape="true"
                            id="computedField5">
                            <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("ID")}]]></xp:this.value>
                        </xp:text>
                    </xp:td>
                </xp:tr>
            </xp:repeat>
        </xp:panel>
    </xe:widgetContainer>

    </xp:view>

SSJS 库

var validateForm = function()
{
var valid = true;
var control;
var control2;
var val;
var val2;

REMOVED business code

function mveTsk(mveDir,pckCat,pckOrd) {

    //OK I am assuming we are only moving something that we can move

    //Set variables
    var pckDoc:NotesDocument;
    var trgDoc:NotesDocument;
    var trgOrd:Integer;
    var tskView = database.getView("(dbAllPCTasksLookup)");
    var key:String = createKey(pckCat,pckOrd);

    //Get the chosen doc
    var query = key;    
    var pckDoc = tskView.getDocumentByKey(query);

    //Get the current order
    var curOrd:Integer = pckDoc.getItemValueInteger("order");

    //Get doc depending on whether we are moving higher or lower
    if (mveDir == "Lower")
        {query = createKey(pckCat,pckOrd-1); 
        var trgDoc = tskView.getDocumentByKey(query);
        pckDoc.replaceItemValue("order",curOrd-1)
        pckDoc.replaceItemValue("key",createKey(pckCat,curOrd-1))
        trgOrd = trgDoc.getItemValueInteger("order");
        trgOrd += 1;
        trgDoc.replaceItemValue("order",trgOrd)
        trgDoc.replaceItemValue("key",createKey(pckCat,trgOrd))}
    else
        {query = createKey(pckCat,pckOrd+1); 
        print (query);
        var trgDoc = tskView.getDocumentByKey(query);   
        pckDoc.replaceItemValue("order",curOrd+1)
        pckDoc.replaceItemValue("key",createKey(pckCat,curOrd+1))
        trgOrd = trgDoc.getItemValueInteger("order");
        trgOrd -= 1;
        trgDoc.replaceItemValue("order",trgOrd)
        trgDoc.replaceItemValue("key",createKey(pckCat,trgOrd))}

    pckDoc.save();
    trgDoc.save();
    resetCategories(pckCat);

    return 
}

function resetCategories (rstCat)
{
    var tskView = database.getView("(dbAllPCTasks)");
    var veCol:NotesViewEntryCollection = tskView.getAllEntriesByKey(rstCat);
    var veCnt = veCol.getCount();
    var curCnt:Integer;
    var tmpDoc:NotesDocument;
    var curOrd:Integer;
    var chgOrd:Integer = 0;
    var doc:NotesDocument

    print (String(veCnt));

    //We have no records so get out
    if (veCnt == 0) {
        return;
    }

    //We have one record, so set this record and get out
    if (veCnt == 1) {
        var entry:NotesViewEntry = veCol.getFirstEntry();
        doc = entry.getDocument()
        doc.replaceItemValue("order",1);
        doc.replaceItemValue("key",createKey(rstCat,1));
        doc.save();
        return;
    }

    //We have one first and one last record, so set these two records and get out
    if (veCnt == 2) {

        //First Entry
        var entry:NotesViewEntry = veCol.getFirstEntry();
        doc = entry.getDocument()
        doc.replaceItemValue("order",1);
        doc.replaceItemValue("key",createKey(rstCat,1));
        doc.save();

        //Second Entry
        var entry:NotesViewEntry = veCol.getNextEntry(entry);
        doc = entry.getDocument()
        doc.replaceItemValue("order",2);
        doc.replaceItemValue("key",createKey(rstCat,2));
        doc.save();
        return;
    }

    //Else we have 3 or more so go through the loop

    print  ("we have more");

    curCnt = 1
    var entry:NotesViewEntry = veCol.getFirstEntry();   
    while (entry != null) {

        doc = entry.getDocument()

        print (String(curCnt));

        //We are the first record
        if (curCnt == 1) {
            doc.replaceItemValue("order",curCnt);
            doc.replaceItemValue("key",createKey(rstCat,curCnt));
            doc.save();
        }

        //We are the last record
        if (curCnt == veCnt) {
            doc.replaceItemValue("order",curCnt);
            doc.replaceItemValue("key",createKey(rstCat,curCnt));
            doc.save();
        }

        //We are neither first nor last; inbetween record
        if ( (curCnt != 1) && (curCnt != veCnt)) {
            doc.replaceItemValue("order",curCnt);
            doc.replaceItemValue("key",createKey(rstCat,curCnt));
            doc.save();
        }

        var tmpentry:NotesViewEntry = veCol.getNextEntry(entry);
        entry.recycle();
        entry = tmpentry;

        curCnt = curCnt + 1
    }

    return
}


    function orderToString (tmpOrd)
    {

        keyString:String        
        tmpOrdStr:String = tmpOrd

        if (len(tmpOrdStr == 1))
        {keyString = "00" + tmpOrdStr;}

        if (len(tmpOrdStr == 2))
        {keyString = "0" + tmpOrdStr;}

        if (len(tmpOrdStr == 3))
        {keyString = tmpOrdStr;}

        return keyString
    }

推荐答案

好吧,我认为有几种方法可以做到这一点.我没有确切的答案,但如果时间允许,我有兴趣对其进行更多探索.您没有说明有多少文档或排序顺序是什么.但是,如果文档包含用于排序顺序的字段,那么我认为您可以轻松地操作它,只需刷新视图即可.不过,我认为这不是一个选择.我相信 java.util.ArrayList 保存您插入对象的顺序.如果没有,那么可能是 LinkedList.无论如何 - 如果您创建了一个列表,然后循环浏览您的视图,将文档 unid 添加到列表中.然后理论上你有一个按视图顺序排列的 Unids 列表.NotesViewNavigator 和 NotesViewEntry 应该非常快地做到这一点.现在,您将其提供给重复控件以从 UNID 获取文档,然后获取您想要的任何其他值.就个人而言,我会将整个文档转换为 java 对象,但这既不存在也不存在.那么你会如何影响订单呢?好吧,如果单位的列表在范围内或任何地方,您只需要一个 Java 方法来上移"或下移".我看到了这个问题 在 ArrayList 中移动项目 并且有一个 Collections.swap方法看起来像.即使这不是答案,也一定有一些很酷的 Java 解决方案.无论如何都不是一个明确的答案,但也许有一些想法供您追求.

Well I think there are a couple ways to do this. I don't have an exact answer though I'm interested in exploring it more if time permits. You don't say how many documents there are or what the sort order is. But if the documents contained a field for the sort order then you could manipulate that easily enough I think and just do a view refresh. I'll assume that's not an option though. I believe java.util.ArrayList holds the order of which you insert objects. If not then maybe LinkedList. Anyway - if you created a List and then looped through your view adding the documents unid to the List. You then in theory have a list of Unids in view order. NotesViewNavigator and NotesViewEntry should be very fast to do that. Now you feed that to a repeat control to get the document from the UNID and then any other values you want. Personally I would convert the whole document to a java Object but that's neither here nor there. So how might you effect the order? Well if the List of the unit's is in Scope or wherever you just need a Java method to "Move Up" or "Move Down". I saw this question Moving items around in an ArrayList and there's a Collections.swap method it looks like. Even if that's not the answer there's gotta be some cool Java solution somewhere. Anyway not a clear answer but maybe some ideas for you to pursue.

(请确保在您收到最终解决方案后发布.)

(Please make sure to post your final solution when you get it. )

这篇关于Xpages 遍历视图并进行更改的最佳方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆