ljm 修改备份

This commit is contained in:
李鹏宇
2025-01-02 11:16:24 +08:00
parent c96c060bd6
commit 55c7ee26e4
14 changed files with 320 additions and 50 deletions
+4 -2
View File
@@ -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);
+5
View File
@@ -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>
+2
View File
@@ -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>