ljm 修改备份
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
'author': 'zxltwins<email:444713077@qq.com>',
|
||||
'website': "www.odoo.com",
|
||||
'version': '17.0',
|
||||
"depends": ["base", 'sale'],
|
||||
"depends": ["base",'sale'],
|
||||
"external_dependencies": {"python": ["mammoth"]},
|
||||
"data": [
|
||||
'security/ir.model.access.csv',
|
||||
@@ -22,7 +22,9 @@
|
||||
],
|
||||
'web.assets_backend': [
|
||||
'preview_easy/static/src/js/qweb.js',
|
||||
'preview_easy/static/src/xml/qweb.xml'
|
||||
'preview_easy/static/src/js/preview_many2one.js',
|
||||
'preview_easy/static/src/xml/qweb.xml',
|
||||
'preview_easy/static/src/xml/preview_many2one.xml',
|
||||
],
|
||||
'web.assets_frontend': [
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,148 @@
|
||||
/** @odoo-module **/
|
||||
import { registry } from "@web/core/registry";
|
||||
import { FileInput } from "@web/core/file_input/file_input";
|
||||
import { useSelectCreate } from "@web/views/fields/relational_utils";
|
||||
import { many2OneField, Many2OneField } from "@web/views/fields/many2one/many2one_field";
|
||||
|
||||
|
||||
export class PreviewMany2OneField extends Many2OneField {
|
||||
static template = "preview_easy.Many2OneField";
|
||||
static components = {
|
||||
...Many2OneField.components,
|
||||
FileInput
|
||||
};
|
||||
static props = {
|
||||
...Many2OneField.props,
|
||||
acceptedFileExtensions: { type: String, optional: true },
|
||||
showSelectBtn: { type: Boolean, optional: true },
|
||||
previewType: { type: String, optional: true },
|
||||
previewString: { type: String, optional: true },
|
||||
className: { type: String, optional: true },
|
||||
};
|
||||
setup() {
|
||||
super.setup();
|
||||
const isToMany = false;
|
||||
this.selectCreate = useSelectCreate({
|
||||
resModel: this.relation,
|
||||
activeActions: {create: false, },
|
||||
onSelected: (resId) => {
|
||||
const resIds = Array.isArray(resId) ? resId : [resId];
|
||||
const values = resIds.map((id) => ({ id }));
|
||||
return this.update(values);
|
||||
},
|
||||
onCreateEdit: ({ context }) => this.openMany2X({ context }),
|
||||
onUnselect: isToMany ? undefined : () => this.update(),
|
||||
});
|
||||
}
|
||||
|
||||
async onFileUploaded(files) {
|
||||
for (const file of files) {
|
||||
if (file.error) {
|
||||
return this.notification.add(file.error, {
|
||||
title: _t("Uploading error"),
|
||||
type: "danger",
|
||||
});
|
||||
}
|
||||
await this.update([{id: file.id, display_name: file.filename}]);
|
||||
}
|
||||
}
|
||||
|
||||
async onFileRemove(deleteId) {
|
||||
await this.update(false);
|
||||
}
|
||||
|
||||
get uploadText() {
|
||||
return this.props.record.fields[this.props.name].string;
|
||||
}
|
||||
|
||||
// 获取文件
|
||||
getFile() {
|
||||
const jsonData = {
|
||||
id: Math.floor(Math.random() * 1000 * 1000 * 1000),
|
||||
jsonrpc: "2.0",
|
||||
method: "call",
|
||||
params: {
|
||||
args: [
|
||||
[this.resId],
|
||||
["id", "name", "mimetype"]
|
||||
],
|
||||
kwargs: {
|
||||
context: this.context,
|
||||
},
|
||||
method: "read",
|
||||
model: this.relation,
|
||||
}
|
||||
};
|
||||
let file;
|
||||
$.ajax({
|
||||
url: "/web/dataset/call_kw/ir.attachment/read",
|
||||
method: "POST",
|
||||
dataType: 'json',
|
||||
async: false, // 设置为同步请求
|
||||
beforeSend: (xhr) => {xhr.setRequestHeader('Content-Type', 'application/json');},
|
||||
data : JSON.stringify(jsonData),
|
||||
success: (result) => {
|
||||
file = result.result[0];
|
||||
}
|
||||
})
|
||||
return file;
|
||||
}
|
||||
|
||||
getUrl(id) {
|
||||
return "/web/content/" + id + "?download=true";
|
||||
}
|
||||
|
||||
preview_Obj(id, name) {
|
||||
var winStr = 'height=600,width=1000,top=' + (screen.height - 600) / 2 + ',left=' + (screen.width - 1000) / 2 + ',toolbar=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,location=no';
|
||||
var newWin = window.open('/web/content/preview/'+ id , name, winStr);
|
||||
newWin.focus();
|
||||
}
|
||||
|
||||
getExtension(file) {
|
||||
return file.name.replace(/^.*\./, "");
|
||||
}
|
||||
|
||||
async onExternalBtnClick() {
|
||||
const domain = this.getDomain();
|
||||
this.selectCreate({
|
||||
domain,
|
||||
context: this.props.record.context,
|
||||
filters: [],
|
||||
title: "Search",
|
||||
});
|
||||
}
|
||||
|
||||
get documentsInstalled() {
|
||||
try {
|
||||
const result = $.ajax({
|
||||
url: "/web/document_module/installed",
|
||||
type: "POST",
|
||||
async: false, // 设置为 false 表示同步请求
|
||||
contentType: "application/json",
|
||||
data: "{}"
|
||||
});
|
||||
return result?.responseJSON?.result?.installed;
|
||||
} catch (error) {
|
||||
console.error('Error fetching document installed status:', error);
|
||||
return false; // 或者其他默认值
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const previewMany2OneField = {
|
||||
...many2OneField,
|
||||
component: PreviewMany2OneField,
|
||||
extractProps({ attrs, context, decorations, options, string }, dynamicInfo) {
|
||||
const result = many2OneField.extractProps.apply(this, arguments);
|
||||
return {
|
||||
...result,
|
||||
acceptedFileExtensions: options.accepted_file_extensions,
|
||||
showSelectBtn: options.show_select_btn === undefined ? true : options.show_select_btn,
|
||||
previewType: options.preview_type,
|
||||
previewString: options.preview_string,
|
||||
className: attrs.class,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
registry.category("fields").add("preview_many2one", previewMany2OneField);
|
||||
@@ -0,0 +1,5 @@
|
||||
.o_field_preview_many2many {
|
||||
.oe_add {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="preview_easy.Many2OneField">
|
||||
<t t-if="props.readonly">
|
||||
<t t-call="preview_easy.Many2OneFieldPreview"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<!-- 如果存在文件显示预览按钮,如果不存在文件,显示上传选择按钮 -->
|
||||
<t t-if="resId">
|
||||
<div class="oe_add">
|
||||
<t t-call="preview_easy.Many2OneFieldPreview"/>
|
||||
<FileInput
|
||||
acceptedFileExtensions="props.acceptedFileExtensions"
|
||||
multiUpload="true"
|
||||
onUpload.bind="onFileUploaded"
|
||||
resModel="props.record.resModel"
|
||||
resId="props.record.resId or 0"
|
||||
>
|
||||
<button class="btn btn-secondary o_attach" data-tooltip="Attach">
|
||||
<span class="fa fa-paperclip" aria-label="Attach"/>
|
||||
<t t-esc="uploadText"/>
|
||||
</button>
|
||||
</FileInput>
|
||||
<button t-if="documentsInstalled and props.showSelectBtn" class="btn btn-secondary o_attach" t-on-click="onExternalBtnClick" data-tooltip="Attach">
|
||||
<i class="fa fa-folder-open-o"/>
|
||||
选择文件
|
||||
</button>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="oe_add">
|
||||
<FileInput
|
||||
acceptedFileExtensions="props.acceptedFileExtensions"
|
||||
multiUpload="true"
|
||||
onUpload.bind="onFileUploaded"
|
||||
resModel="props.record.resModel"
|
||||
resId="props.record.resId or 0"
|
||||
>
|
||||
<button class="btn btn-secondary o_attach" data-tooltip="Attach">
|
||||
<span class="fa fa-paperclip" aria-label="Attach"/>
|
||||
<t t-esc="uploadText"/>
|
||||
</button>
|
||||
</FileInput>
|
||||
<button t-if="documentsInstalled and props.showSelectBtn" class="btn btn-secondary o_attach" t-on-click="onExternalBtnClick" data-tooltip="Attach">
|
||||
<i class="fa fa-folder-open-o"/>
|
||||
选择文件
|
||||
</button>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-name="preview_easy.Many2OneFieldPreview" owl="1">
|
||||
<t t-set="editable" t-value="!props.readonly"/>
|
||||
<t t-set="file" t-value="getFile()"/>
|
||||
<!-- 预览按钮 -->
|
||||
<t t-if="props.previewType and props.previewType === 'button'">
|
||||
<button class="btn btn-secondary o_attach" t-on-click.stop="() => this.preview_Obj()" data-tooltip="Attach">
|
||||
<i class="fa fa-eye"/>
|
||||
<span t-if="props.previewString" t-out="props.previewString"/>
|
||||
<span t-else="" t-out="'预览文件'"/>
|
||||
</button>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div t-attf-class="o_attachment o_attachment_many2many #{ editable ? 'o_attachment_editable' : '' } #{upload ? 'o_attachment_uploading' : ''}" t-att-title="file.name">
|
||||
<div class="o_attachment_wrap">
|
||||
<t t-set="ext" t-value="getExtension(file)"/>
|
||||
<t t-set="url" t-value="getUrl(file.id)"/>
|
||||
<div class="o_image_box float-start" t-att-data-tooltip="'Preview ' + file.name">
|
||||
<span class="o_image o_hover" t-on-click.stop="() => this.preview_Obj(file.id,file.name)" t-att-data-mimetype="file.mimetype" t-att-data-ext="ext" role="img"/>
|
||||
</div>
|
||||
|
||||
<div class="caption">
|
||||
<a class="ml4" t-att-data-tooltip="'Download ' + file.name" t-att-href="getUrl(file.id)"><t t-esc='file.name'/></a>
|
||||
</div>
|
||||
<div class="caption small">
|
||||
<a class="ml4 small text-uppercase" t-att-href="getUrl(file.id)"><b><t t-esc='ext'/></b></a>
|
||||
<div t-if="editable" class="progress o_attachment_progress_bar">
|
||||
<div class="progress-bar progress-bar-striped active" style="width: 100%">Uploading</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="o_attachment_uploaded"><i class="text-success fa fa-check" role="img" aria-label="Uploaded" title="Uploaded"/></div>
|
||||
<div t-if="editable" class="o_attachment_delete" t-on-click.stop="() => this.onFileRemove(file.id)"><span class="text-white" role="img" aria-label="Delete" title="Delete">×</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -8,8 +8,10 @@
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="attachment_ids" widget="preview_many2many"/>
|
||||
<!-- <field name="attachment_ids" widget="many2many_tags"/> -->
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user