0

我一直在尝试让签名面板在 grails 中工作。在客户端,一切看起来都正常,但我一直在努力研究如何将签名保存到数据库记录中。

我尝试了几个不同的版本,最后一个版本最接近描述如何使用 php、ruby 或 python 使用 ImageMagic 等。但是,尝试在 groovy 中执行此操作让我迷失了方向,因为我对如何编码还有些陌生。另外,当它将在云代工厂上运行时,我不确定是否使用 3rd 方实用程序。

名为 SignaturePanel 的插件,看起来真的和其他的一样... jes-sherborne/jquery-signature-panel-plugin

这是我文件中的代码。

首先,create.gsp 包含 Javascript 代码。

<title><g:message code="default.create.label" args="[entityName]" /></title>
        <!--  jQuery signature element code begins here -->
        <!--[if lt IE 9]><script type="text/javascript" src="${resource(dir: 'js', file: 'excanvas.compiled.js')}"></script><![endif]-->
    <script type="text/javascript" src="${resource(dir: 'js', file: 'jquery-1.4.4.min.js')}"></script>
    <script type="text/javascript" src="${resource(dir: 'js', file: 'jquery.signature-panel.js')}"></script>

    <link rel="stylesheet" href="${resource(dir: 'css', file: 'jquery.signature-panel.css')}" type="text/css"/>


    <script type="text/javascript">

        function signatureOK(signatureData) {
            // Send the signature to the server and generate an image file.
            $.ajax({
                url:"processSignature",
                type:"POST",
                data:JSON.stringify(signatureData),
                contentType:"application/json; charset=utf-8",
                dataType:"text",
                success: function(data, textStatus, jqXHR){
                    $("#latest-signature").attr("src", data);
                },
                error: function(jqXHR, textStatus, errorThrown) {
                    console.log(textStatus);
                    console.log(errorThrown);
                }
            });
            $("#sig-panel").signaturePanel("clear");
        }

        function signatureCancel() {
            alert("Cancelled.");
        }

        $(document).ready(function() {
            $("#sig-panel").signaturePanel({
                okCallback: signatureOK,
                cancelCallback: signatureCancel
            });
        });

    </script>

_form.gsp

<!-- Signature Panel Begins Here -->

    <label for="sig"><g:message code="salesOrder.sig.label" default="Customer Signature" /></label>
    <div class="fieldcontain" ${hasErrors(bean: salesOrderInstance, field: 'sig','error')} id="sig-panel" style="width: 500px; height: 150px; border: 0px none"></div>
    <canvas id="latest-signature" style="width: 500px; height: 150px; border: 0px none"></canvas>

<!-- End of Signature Panel -->

控制器

// Capture Customer Signature JSON Data, Processes to Image, and Stream to Database
    @Secured(['ROLE_ADMIN','ROLE_SALES'])
    def processSignature() {
        flash.message = message(code: 'default.created.message', args: [message(code: 'salesOrder.label', default: 'Signature'), ])
        // groovy code here 
        // We need to read the JSON POST data
         InputStream body = request.getInputStream();
         log.info(body) // nothing happens here
    }

这是我试图弄清楚如何在 groovy 中执行的 Ruby 示例之一。*(或者如果有更好的方法......在客户端,只需右键单击并保存图像。不太清楚为什么这对我来说太难了)

### Generating image files on the server using Ruby

The Ruby library uses ImageMagick to generate a `Magick::Image` object, which you can use to write image files or stream the data in a variety of formats (PNG, JPEG, etc.). By default, the function will generate an image with the same pixel measurements as were originally captured on the client. You can also specify the size of the generated image, and SignaturePanel will scale the signature appropriately to fit within these bounds.

To generate the image, you will write code like this:

```ruby
require 'signature-panel.rb'
...

post '/process-signature' do
    image = SignaturePanel::GenerateImage(request.body.read)
    filename = 'latest-signature.png'

    image.write(filename)

    # If you want to stream your PNG directly to a database instead of saving a file,
    # you can get a binary stream like this:
    # image.to_blob {self.format = "PNG"}

    content_type :text

    # Send the name of the newly-generated file to the client
    body filename
end
```

所以我的问题再次是,如何使用 groovy 将签名与所有其他表单数据一起保存到数据库中?

我也应该从我的域类中提到

byte[] sig

sig nullable: true, maxSize: 1048567

一旦我们解决了这个挑战,我们就可以让这只小狗睡觉了;)

4

1 回答 1

0

我一直只是将 JSON 数据保存到文本类型字段(如 Oracle 中的 CLOB)中,然后使用库函数将其显示在页面上:

$("#signature-display").signaturePanel("drawClickstreamToCanvas", signatureData); 

signatureDataJSON 字符串在哪里。

因此,您可以更改域类以包含

String sig

sig nullable: true, maxSize: 1048567

这也允许你做一些我认为很酷的事情,尽管它是否有用取决于你的应用程序。您可以重新创建签名的实际签名并为其设置动画:

$("#signature-replay").signaturePanel("animateClickstreamToCanvas", signatureData, callback);

文档解释了可选callback功能。不过我从来没有用过。

如果您更改部分 ajax 调用,请删除该contentType行,因为您发送的是直接文本并设置隐藏字段

type:"POST",
data:{"signature": JSON.stringify(signatureData)},
//contentType:"application/json; charset=utf-8",
success: function(data, textStatus, jqXHR){
    //set the hidden field value
    $('#sig').val(JSON.stringify(signatureData));
    //show signature on same page as preview (optional)
    $("#latest-signature").signaturePanel("drawClickstreamToCanvas", signatureData);
},
....

然后将表单中的隐藏字段添加为

<g:hiddenField name="sig" />

因此,现在当他们输入签名并点击“确定”时,processSignature实际上不会做任何事情 - 只是充当占位符。AJAX 调用将设置页面上隐藏字段的值。然后,当他们提交整个表单(以及其他数据)时,普通save()方法将sig作为另一个参数获取,并自动将其保存到sig域类中的字段中。

processSignature您可以在方法中将数据作为普通字符串访问,就params.signature好像您需要:

def processSignature() {
    flash.message = message(code: 'default.created.message', args: [message(code: 'salesOrder.label', default: 'Signature'), ])
    def signature = params.signature
    log.info(signature)
    response.contentType = "application/json"
    render """{"ok":true}"""
}
于 2013-01-12T01:23:23.197 回答